css_ast/functions/
stripes_function.rs

1use css_parse::{CommaSeparated, Cursor, Function, Parse, Parser, Peek, Result as ParserResult, function_set};
2use csskit_derives::{Parse, Peek, ToCursors, ToSpan, Visitable};
3
4use crate::{types::Color, units::LengthPercentageOrFlex};
5
6function_set!(pub struct StripesFunctionName "stripes");
7
8/// <https://drafts.csswg.org/css-images-4/#typedef-image-1d>
9///
10/// ```text,ignore
11/// <stripes()> = stripes( <color-stripe># )
12/// <color-stripe> = <color> && [ <length-percentage> | <flex> ]?
13/// ```
14#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
16#[visit]
17pub struct StripesFunction<'a>(Function<StripesFunctionName, CommaSeparated<'a, ColorStripe>>);
18
19/// <https://drafts.csswg.org/css-images-4/#typedef-color-stripe>
20///
21/// ```text,ignore
22/// <color-stripe> = <color> && [ <length-percentage> | <flex> ]?
23/// ```
24#[derive(ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
25#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
26#[visit(children)]
27pub struct ColorStripe {
28	pub color: Color,
29	pub thickness: Option<LengthPercentageOrFlex>,
30}
31
32impl<'a> Peek<'a> for ColorStripe {
33	fn peek(p: &Parser<'a>, c: Cursor) -> bool {
34		Color::peek(p, c) || LengthPercentageOrFlex::peek(p, c)
35	}
36}
37
38impl<'a> Parse<'a> for ColorStripe {
39	fn parse(p: &mut Parser<'a>) -> ParserResult<Self> {
40		let mut color = p.parse_if_peek::<Color>()?;
41		let thickness = p.parse_if_peek::<LengthPercentageOrFlex>()?;
42		if color.is_none() {
43			color = Some(p.parse::<Color>()?);
44		}
45		Ok(Self { color: color.unwrap(), thickness })
46	}
47}
48
49#[cfg(test)]
50mod tests {
51	use super::*;
52	use css_parse::assert_parse;
53
54	#[test]
55	fn size_test() {
56		assert_eq!(std::mem::size_of::<StripesFunction>(), 64);
57		assert_eq!(std::mem::size_of::<ColorStripe>(), 160);
58	}
59
60	#[test]
61	fn test_writes() {
62		assert_parse!(StripesFunction, "stripes(red 1fr,green 2fr,blue 100px)");
63		assert_parse!(
64			StripesFunction,
65			"stripes(0.1fr red,0.2fr green,100px blue)",
66			"stripes(red 0.1fr,green 0.2fr,blue 100px)"
67		);
68		assert_parse!(
69			StripesFunction,
70			"stripes(red 1fr,2fr green,blue 100px)",
71			"stripes(red 1fr,green 2fr,blue 100px)"
72		);
73	}
74}