use cssparser::{Parser, match_ignore_ascii_case};
use crate::layout::style::{
CssToken, FromCss, MakeComputed, ParseResult, declare_enum_from_css_impl,
};
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub enum BackgroundRepeatStyle {
#[default]
Repeat,
NoRepeat,
Space,
Round,
}
declare_enum_from_css_impl!(
BackgroundRepeatStyle,
"repeat" => BackgroundRepeatStyle::Repeat,
"no-repeat" => BackgroundRepeatStyle::NoRepeat,
"space" => BackgroundRepeatStyle::Space,
"round" => BackgroundRepeatStyle::Round,
);
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct BackgroundRepeat(pub BackgroundRepeatStyle, pub BackgroundRepeatStyle);
impl MakeComputed for BackgroundRepeat {}
impl BackgroundRepeat {
pub const fn repeat() -> Self {
Self(BackgroundRepeatStyle::Repeat, BackgroundRepeatStyle::Repeat)
}
pub const fn no_repeat() -> Self {
Self(
BackgroundRepeatStyle::NoRepeat,
BackgroundRepeatStyle::NoRepeat,
)
}
pub const fn space() -> Self {
Self(BackgroundRepeatStyle::Space, BackgroundRepeatStyle::Space)
}
pub const fn round() -> Self {
Self(BackgroundRepeatStyle::Round, BackgroundRepeatStyle::Round)
}
}
impl<'i> FromCss<'i> for BackgroundRepeat {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
let state = input.state();
let ident = input.expect_ident()?;
match_ignore_ascii_case! { ident,
"repeat-x" => return Ok(BackgroundRepeat(BackgroundRepeatStyle::Repeat, BackgroundRepeatStyle::NoRepeat)),
"repeat-y" => return Ok(BackgroundRepeat(BackgroundRepeatStyle::NoRepeat, BackgroundRepeatStyle::Repeat)),
_ => {}
}
input.reset(&state);
let x = BackgroundRepeatStyle::from_css(input)?;
let y = input
.try_parse(BackgroundRepeatStyle::from_css)
.unwrap_or(x);
Ok(BackgroundRepeat(x, y))
}
fn valid_tokens() -> &'static [CssToken] {
&[
CssToken::Keyword("repeat-x"),
CssToken::Keyword("repeat-y"),
CssToken::Keyword("repeat"),
CssToken::Keyword("no-repeat"),
CssToken::Keyword("space"),
CssToken::Keyword("round"),
]
}
}
pub type BackgroundRepeats = Box<[BackgroundRepeat]>;
impl<'i> FromCss<'i> for BackgroundRepeats {
fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
let mut values = Vec::new();
values.push(BackgroundRepeat::from_css(input)?);
while input.expect_comma().is_ok() {
values.push(BackgroundRepeat::from_css(input)?);
}
Ok(values.into_boxed_slice())
}
fn valid_tokens() -> &'static [CssToken] {
BackgroundRepeat::valid_tokens()
}
}