use cssparser::Parser;
use crate::layout::style::{
CssToken, FromCss, GridPlacementKeyword, GridPlacementSpan, MakeComputed, ParseResult,
tw::TailwindPropertyParser,
};
use crate::rendering::Sizing;
use super::GridPlacement;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct GridLine {
pub start: GridPlacement,
pub end: GridPlacement,
}
impl MakeComputed for GridLine {
fn make_computed(&mut self, sizing: &Sizing) {
self.start.make_computed(sizing);
self.end.make_computed(sizing);
}
}
impl GridLine {
pub const fn full() -> Self {
Self {
start: GridPlacement::Line(1),
end: GridPlacement::Line(-1),
}
}
pub const fn span(span: GridPlacementSpan) -> Self {
Self {
start: GridPlacement::Span(span),
end: GridPlacement::Span(span),
}
}
pub const fn start(start: GridPlacement) -> Self {
Self {
start,
end: GridPlacement::auto(),
}
}
pub const fn end(end: GridPlacement) -> Self {
Self {
start: GridPlacement::auto(),
end,
}
}
}
impl From<GridLine> for taffy::Line<taffy::GridPlacement> {
fn from(line: GridLine) -> Self {
Self {
start: line.start.into(),
end: line.end.into(),
}
}
}
impl From<&GridLine> for taffy::Line<taffy::GridPlacement> {
fn from(line: &GridLine) -> Self {
Self {
start: match &line.start {
GridPlacement::Keyword(GridPlacementKeyword::Auto) => taffy::GridPlacement::Auto,
GridPlacement::Line(index) => taffy::GridPlacement::Line((*index).into()),
GridPlacement::Span(GridPlacementSpan::Span(span)) => taffy::GridPlacement::Span(*span),
GridPlacement::Named(_) => taffy::GridPlacement::Auto,
},
end: match &line.end {
GridPlacement::Keyword(GridPlacementKeyword::Auto) => taffy::GridPlacement::Auto,
GridPlacement::Line(index) => taffy::GridPlacement::Line((*index).into()),
GridPlacement::Span(GridPlacementSpan::Span(span)) => taffy::GridPlacement::Span(*span),
GridPlacement::Named(_) => taffy::GridPlacement::Auto,
},
}
}
}
impl<'i> FromCss<'i> for GridLine {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
let first = GridPlacement::from_css(input)?;
let second = if input.try_parse(|i| i.expect_delim('/')).is_ok() {
Some(GridPlacement::from_css(input)?)
} else {
None
};
Ok(GridLine {
start: first,
end: second.unwrap_or_default(),
})
}
fn valid_tokens() -> &'static [CssToken] {
&[
CssToken::Keyword("span"),
CssToken::Token("number"),
CssToken::Token("ident"),
]
}
}
impl TailwindPropertyParser for GridLine {
fn parse_tw(suffix: &str) -> Option<Self> {
let number = suffix.parse::<i16>().ok()?;
Some(GridLine {
start: GridPlacement::Line(number),
end: GridPlacement::auto(),
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_line() {
assert_eq!(
GridLine::from_str("span 2 / 3"),
Ok(GridLine {
start: GridPlacement::span(2),
end: GridPlacement::Line(3),
})
);
}
}