1use super::prelude::*;
2use crate::PaletteIdentifier;
3#[cfg(feature = "visitable")]
4use crate::visit::{NodeId, QueryableNode};
5use csskit_proc_macro::syntax;
6
7#[node]
16#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
17#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
18#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit, queryable(skip))]
19#[cfg_attr(
20 feature = "css_feature_data",
21 derive(::csskit_derives::ToCSSFeature),
22 css_feature("css.at-rules.font-palette-values")
23)]
24#[derive(csskit_derives::NodeWithMetadata)]
25#[metadata(node_kinds = AtRule, used_at_rules = FontPaletteValues, property_kinds = Name)]
26pub struct FontPaletteValuesRule<'a> {
27 #[cfg_attr(feature = "visitable", visit(skip))]
28 #[atom(CssAtomSet::FontPaletteValues)]
29 pub name: T![AtKeyword],
30 pub prelude: PaletteIdentifier,
31 #[metadata(block)]
32 pub block: FontPaletteValuesRuleBlock<'a>,
33}
34
35#[cfg(feature = "visitable")]
36impl<'a> QueryableNode for FontPaletteValuesRule<'a> {
37 const NODE_ID: NodeId = NodeId::FontPaletteValuesRule;
38
39 fn get_property(&self, kind: PropertyKind) -> Option<Cursor> {
40 match kind {
41 PropertyKind::Name => Some(self.prelude.into()),
42 _ => None,
43 }
44 }
45}
46
47#[node]
48#[derive(Parse, Peek, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
49#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
50#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(children))]
51#[derive(csskit_derives::NodeWithMetadata)]
52pub struct FontPaletteValuesRuleBlock<'a>(DeclarationList<'a, FontPaletteValuesRuleStyleValue<'a>, CssMetadata>);
53
54#[node]
56#[derive(ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
57#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
58#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
59#[derive(csskit_derives::NodeWithMetadata)]
60pub enum FontPaletteValuesRuleStyleValue<'a> {
61 FontFamily(FontPaletteValuesFontFamilyValue<'a>),
62 BasePalette(BasePaletteValue<'a>),
63 OverrideColors(OverrideColorsValue<'a>),
64 Unknown(ComponentValues<'a>),
65}
66
67impl<'a> DeclarationValue<'a, CssMetadata> for FontPaletteValuesRuleStyleValue<'a> {
68 fn valid_declaration_name<I>(p: &Parser<'a, I>, c: Cursor) -> bool
69 where
70 I: Iterator<Item = Cursor> + Clone,
71 {
72 matches!(
73 p.to_atom::<CssAtomSet>(c),
74 CssAtomSet::FontFamily | CssAtomSet::BasePalette | CssAtomSet::OverrideColors
75 )
76 }
77
78 fn is_unknown(&self) -> bool {
79 matches!(self, Self::Unknown(_))
80 }
81
82 fn needs_computing(&self) -> bool {
83 matches!(self, Self::Unknown(_))
84 }
85
86 fn parse_declaration_value<I>(p: &mut Parser<'a, I>, c: Cursor) -> ParserResult<Self>
87 where
88 I: Iterator<Item = Cursor> + Clone,
89 {
90 Ok(match p.to_atom::<CssAtomSet>(c) {
91 CssAtomSet::FontFamily => Self::FontFamily(p.parse::<FontPaletteValuesFontFamilyValue<'a>>()?),
92 CssAtomSet::BasePalette => Self::BasePalette(p.parse::<BasePaletteValue<'a>>()?),
93 CssAtomSet::OverrideColors => Self::OverrideColors(p.parse::<OverrideColorsValue<'a>>()?),
94 _ => Self::Unknown(p.parse::<ComponentValues<'a>>()?),
95 })
96 }
97}
98
99#[syntax(" <font-family-name># ")]
105#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
106#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
107#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
108#[derive(csskit_derives::NodeWithMetadata)]
109pub struct FontPaletteValuesFontFamilyValue<'a>;
110
111#[syntax(" light | dark | <integer [0,∞]> ")]
117#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
118#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
119#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
120#[derive(csskit_derives::NodeWithMetadata)]
121pub enum BasePaletteValue<'a> {}
122
123#[syntax(" [ <integer [0,∞]> <color> ]# ")]
129#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
130#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
131#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
132#[derive(csskit_derives::NodeWithMetadata)]
133pub struct OverrideColorsValue<'a>;
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138 use css_parse::assert_parse;
139
140 #[test]
141 fn test_writes() {
142 assert_parse!(CssAtomSet::ATOMS, FontPaletteValuesRule, "@font-palette-values --cooler{}");
143 assert_parse!(CssAtomSet::ATOMS, FontPaletteValuesRule, "@font-palette-values --cooler{base-palette:dark}");
144 assert_parse!(
145 CssAtomSet::ATOMS,
146 FontPaletteValuesRule,
147 "@font-palette-values --cooler{font-family:Bixa;base-palette:1;override-colors:0 red,1 #0f0}"
148 );
149 assert_parse!(
150 CssAtomSet::ATOMS,
151 FontPaletteValuesRule,
152 "@font-palette-values --Alternate{font-family:\"Bungee Spice\",Bixa}"
153 );
154 }
155}