css_ast/functions/
stripes_function.rs1use 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#[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#[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}