takumi_css/style/properties/grid/
grid_area.rs1use crate::style::unexpected_token;
2use cssparser::Parser;
3
4use crate::style::{CssSyntaxKind, CssToken, FromCss, GridPlacement, ParseResult};
5
6#[derive(Debug, Clone, PartialEq, Default)]
8pub struct GridArea {
9 pub row_start: GridPlacement,
11 pub column_start: GridPlacement,
13 pub row_end: GridPlacement,
15 pub column_end: GridPlacement,
17}
18
19impl<'i> FromCss<'i> for GridArea {
20 const VALID_TOKENS: &'static [CssToken] = &[
21 CssToken::Keyword("auto"),
22 CssToken::Keyword("span"),
23 CssToken::Syntax(CssSyntaxKind::Ident),
24 CssToken::Syntax(CssSyntaxKind::Number),
25 ];
26
27 fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
28 let mut values = vec![GridPlacement::from_css(input)?];
29
30 while values.len() < 4 && input.try_parse(|parser| parser.expect_delim('/')).is_ok() {
31 values.push(GridPlacement::from_css(input)?);
32 }
33
34 if !input.is_exhausted() {
35 return Err(unexpected_token!(
36 input.current_source_location(),
37 input.next()?,
38 ));
39 }
40
41 let row_start = values[0].clone();
42 let column_start = match values.get(1) {
43 Some(value) => value.clone(),
44 None if matches!(row_start, GridPlacement::Named(_)) => row_start.clone(),
45 None => GridPlacement::default(),
46 };
47 let row_end = match values.get(2) {
48 Some(value) => value.clone(),
49 None if matches!(row_start, GridPlacement::Named(_)) => row_start.clone(),
50 None => GridPlacement::default(),
51 };
52 let column_end = match values.get(3) {
53 Some(value) => value.clone(),
54 None if matches!(column_start, GridPlacement::Named(_)) => column_start.clone(),
55 None => GridPlacement::default(),
56 };
57
58 Ok(Self {
59 row_start,
60 column_start,
61 row_end,
62 column_end,
63 })
64 }
65}