use crate::layout::style::unexpected_token;
use cssparser::{Parser, Token};
use crate::layout::style::{CssSyntaxKind, CssToken, FromCss, ParseResult, ToCss};
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum GridRepetitionKeyword {
AutoFill,
AutoFit,
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum GridRepetitionCount {
Keyword(GridRepetitionKeyword),
Count(u16),
}
impl From<GridRepetitionCount> for taffy::RepetitionCount {
fn from(repetition: GridRepetitionCount) -> Self {
match repetition {
GridRepetitionCount::Keyword(GridRepetitionKeyword::AutoFill) => {
taffy::RepetitionCount::AutoFill
}
GridRepetitionCount::Keyword(GridRepetitionKeyword::AutoFit) => {
taffy::RepetitionCount::AutoFit
}
GridRepetitionCount::Count(count) => taffy::RepetitionCount::Count(count),
}
}
}
impl<'i> FromCss<'i> for GridRepetitionCount {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
let location = input.current_source_location();
if let Ok(ident) = input.try_parse(Parser::expect_ident_cloned) {
let ident_str = ident.as_ref();
if ident_str.eq_ignore_ascii_case("auto-fill") {
return Ok(GridRepetitionCount::Keyword(
GridRepetitionKeyword::AutoFill,
));
}
if ident_str.eq_ignore_ascii_case("auto-fit") {
return Ok(GridRepetitionCount::Keyword(GridRepetitionKeyword::AutoFit));
}
return Err(unexpected_token!(location, &Token::Ident(ident)));
}
let token = input.next()?;
match *token {
Token::Number {
int_value, value, ..
} => {
let count: i64 = if let Some(iv) = int_value {
iv as i64
} else {
value as i64
};
if count < 0 {
return Err::<Self, _>(
location
.new_basic_unexpected_token_error(token.clone())
.into(),
);
}
Ok(GridRepetitionCount::Count(count as u16))
}
_ => Err(unexpected_token!(location, token)),
}
}
const VALID_TOKENS: &'static [CssToken] = &[
CssToken::Keyword("auto-fill"),
CssToken::Keyword("auto-fit"),
CssToken::Syntax(CssSyntaxKind::Number),
];
}
impl ToCss for GridRepetitionKeyword {
fn to_css<W: std::fmt::Write>(&self, dest: &mut W) -> std::fmt::Result {
match self {
Self::AutoFill => dest.write_str("auto-fill"),
Self::AutoFit => dest.write_str("auto-fit"),
}
}
}
impl ToCss for GridRepetitionCount {
fn to_css<W: std::fmt::Write>(&self, dest: &mut W) -> std::fmt::Result {
match self {
Self::Keyword(kw) => kw.to_css(dest),
Self::Count(c) => write!(dest, "{}", c),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_repetition_count() {
assert_eq!(
GridRepetitionCount::from_str("auto-fill"),
Ok(GridRepetitionCount::Keyword(
GridRepetitionKeyword::AutoFill
))
);
assert_eq!(
GridRepetitionCount::from_str("auto-fit"),
Ok(GridRepetitionCount::Keyword(GridRepetitionKeyword::AutoFit))
);
assert_eq!(
GridRepetitionCount::from_str("3"),
Ok(GridRepetitionCount::Count(3))
);
}
}