css_ast/rules/
property.rs

1use css_parse::{
2	AtRule, Build, Cursor, DeclarationList, DeclarationValue, Parser, Peek, Result as ParserResult, T, atkeyword_set,
3	keyword_set, syntax::ComponentValues,
4};
5use csskit_derives::{IntoCursor, Parse, Peek, ToCursors, ToSpan, Visitable};
6
7use crate::Computed;
8
9atkeyword_set!(pub struct AtPropertyKeyword "property");
10
11// https://drafts.csswg.org/cssom-1/#csspagerule
12// https://drafts.csswg.org/css-page-3/#at-page-rule
13#[derive(Parse, Peek, ToSpan, ToCursors, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
15#[cfg_attr(feature = "css_feature_data", derive(::csskit_derives::ToCSSFeature), css_feature("css.at-rules.property"))]
16#[visit]
17pub struct PropertyRule<'a>(pub AtRule<AtPropertyKeyword, PropertyPrelude, PropertyRuleBlock<'a>>);
18
19#[derive(Parse, Peek, ToSpan, ToCursors, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
21#[visit(self)]
22pub struct PropertyPrelude(T![DashedIdent]);
23
24#[derive(Parse, Peek, ToSpan, ToCursors, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
26pub struct PropertyRuleBlock<'a>(DeclarationList<'a, PropertyRuleValue<'a>>);
27
28keyword_set!(pub enum PropertyRulePropertyId { InitialValue: "initial-value", Inherits: "inherits", Syntax: "syntax" });
29
30#[derive(ToSpan, ToCursors, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
32#[visit(children)]
33pub enum PropertyRuleValue<'a> {
34	InitialValue(ComponentValues<'a>),
35	Syntax(SyntaxValue),
36	Inherits(InheritsValue),
37	Unknown(ComponentValues<'a>),
38}
39
40keyword_set!(
41	#[derive(Visitable)]
42	#[visit(self)]
43	pub enum InheritsValue {
44		True: "true",
45		False: "false"
46	}
47);
48
49#[derive(Parse, Peek, ToCursors, IntoCursor, Visitable, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
50#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
51#[visit(self)]
52pub struct SyntaxValue(T![String]);
53
54impl<'a> DeclarationValue<'a> for PropertyRuleValue<'a> {
55	type ComputedValue = Computed<'a>;
56
57	fn valid_declaration_name(p: &Parser<'a>, c: Cursor) -> bool {
58		PropertyRulePropertyId::peek(p, c)
59	}
60
61	fn is_unknown(&self) -> bool {
62		matches!(self, Self::Unknown(_))
63	}
64
65	fn is_initial(&self) -> bool {
66		false
67	}
68
69	fn is_inherit(&self) -> bool {
70		false
71	}
72
73	fn is_unset(&self) -> bool {
74		false
75	}
76
77	fn is_revert(&self) -> bool {
78		false
79	}
80
81	fn is_revert_layer(&self) -> bool {
82		false
83	}
84
85	fn needs_computing(&self) -> bool {
86		matches!(self, Self::Unknown(_))
87	}
88
89	fn parse_declaration_value(p: &mut Parser<'a>, c: Cursor) -> ParserResult<Self> {
90		if !PropertyRulePropertyId::peek(p, c) {
91			Ok(Self::Unknown(p.parse::<ComponentValues<'a>>()?))
92		} else {
93			Ok(match PropertyRulePropertyId::build(p, c) {
94				PropertyRulePropertyId::InitialValue(_) => Self::InitialValue(p.parse::<ComponentValues<'a>>()?),
95				PropertyRulePropertyId::Inherits(_) => Self::Inherits(p.parse::<InheritsValue>()?),
96				PropertyRulePropertyId::Syntax(_) => Self::Syntax(p.parse::<SyntaxValue>()?),
97			})
98		}
99	}
100}
101
102#[cfg(test)]
103mod tests {
104	use super::*;
105	use css_parse::assert_parse;
106
107	#[test]
108	fn size_test() {
109		assert_eq!(std::mem::size_of::<PropertyRule>(), 104);
110	}
111
112	#[test]
113	fn test_writes() {
114		assert_parse!(PropertyRule, r#"@property --foo{initial-value:0;inherits:false;syntax:"<length>"}"#);
115	}
116}