use cssparser::Parser;
use super::{parse_line_names, write_space_separated};
use crate::style::{
CssSyntaxKind, CssToken, FromCss, GridTrackSize, MakeComputed, ParseResult, SizingContext, ToCss,
};
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub struct GridRepeatTrack {
pub size: GridTrackSize,
pub names: Vec<String>,
pub end_names: Option<Vec<String>>,
}
impl MakeComputed for GridRepeatTrack {
fn make_computed(&mut self, sizing: &SizingContext) {
self.size.make_computed(sizing);
}
}
impl<'i> FromCss<'i> for GridRepeatTrack {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
let mut names: Vec<String> = Vec::new();
while input.try_parse(Parser::expect_square_bracket_block).is_ok() {
names.extend(parse_line_names(input)?);
}
let size = GridTrackSize::from_css(input)?;
while input.try_parse(Parser::expect_square_bracket_block).is_ok() {
names.extend(parse_line_names(input)?);
}
Ok(GridRepeatTrack {
size,
names,
end_names: None,
})
}
const VALID_TOKENS: &'static [CssToken] = &[
CssToken::Syntax(CssSyntaxKind::LineNames),
CssToken::Syntax(CssSyntaxKind::TrackSize),
];
}
impl ToCss for GridRepeatTrack {
fn to_css<W: std::fmt::Write>(&self, dest: &mut W) -> std::fmt::Result {
if !self.names.is_empty() {
dest.write_str("[")?;
write_space_separated(dest, &self.names)?;
dest.write_str("] ")?;
}
self.size.to_css(dest)?;
if let Some(end_names) = &self.end_names
&& !end_names.is_empty()
{
dest.write_str(" [")?;
write_space_separated(dest, end_names)?;
dest.write_str("]")?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use crate::style::GridLength;
use super::*;
use cssparser::{Parser, ParserInput};
#[test]
fn test_parse_repeat_track_with_names() {
let mut parser_input = ParserInput::new("[a b] 1fr [c]");
let mut parser = Parser::new(&mut parser_input);
let track = GridRepeatTrack::from_css(&mut parser);
assert_eq!(
track,
Ok(GridRepeatTrack {
size: GridTrackSize::Fixed(GridLength::Fr(1.0)),
names: vec!["a".to_string(), "b".to_string(), "c".to_string()],
end_names: None,
})
);
}
}