use crate::layout::style::unexpected_token;
use cssparser::{Parser, Token};
use taffy::CompactLength;
use crate::{
layout::style::{CssToken, FromCss, Length, MakeComputed, ParseResult},
rendering::Sizing,
};
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum FrLength {
Fr(f32),
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[non_exhaustive]
pub enum GridLength {
Fr(f32),
Unit(Length),
}
impl GridLength {
pub(crate) fn to_compact_length(self, sizing: &Sizing) -> CompactLength {
match self {
GridLength::Fr(fr) => CompactLength::fr(fr),
GridLength::Unit(unit) => unit.to_compact_length(sizing),
}
}
}
impl<'i> FromCss<'i> for GridLength {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
if let Ok(unit) = input.try_parse(Length::from_css) {
return Ok(GridLength::Unit(unit));
}
let location = input.current_source_location();
let token = input.next()?;
let Token::Dimension { value, unit, .. } = &token else {
return Err(unexpected_token!(location, token));
};
if !unit.eq_ignore_ascii_case("fr") {
return Err(unexpected_token!(location, token));
}
Ok(GridLength::Fr(*value))
}
const VALID_TOKENS: &'static [CssToken] = Length::<true>::VALID_TOKENS;
}
impl MakeComputed for GridLength {
fn make_computed(&mut self, sizing: &Sizing) {
if let GridLength::Unit(unit) = self {
unit.make_computed(sizing);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_fr_and_unit() {
assert_eq!(GridLength::from_str("1fr"), Ok(GridLength::Fr(1.0)));
assert_eq!(
GridLength::from_str("10px"),
Ok(GridLength::Unit(Length::Px(10.0)))
);
}
}