use {
crate::{
domain::CounterStyleIdent,
parsers::{Parse, ParserContext},
CustomParseError,
},
cssparser::{ParseError, Parser, ToCss},
std::fmt,
};
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum System {
Cyclic,
Numeric,
Alphabetic,
Symbolic,
Additive,
Fixed {
first_symbol_value: Option<i32>,
},
Extends(CounterStyleIdent),
}
impl Parse for System {
fn parse<'i, 't>(
_context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i, CustomParseError<'i>>> {
use self::System::*;
let identifier = input.expect_ident_cloned()?;
match_ignore_ascii_case! {
&*identifier,
"cyclic" => Ok(Cyclic),
"numeric" => Ok(Numeric),
"alphabetic" => Ok(Alphabetic),
"symbolic" => Ok(Symbolic),
"additive" => Ok(Additive),
"fixed" =>
{
let first_symbol_value = input.r#try(|i| i.expect_integer()).ok();
Ok(Fixed { first_symbol_value })
},
"extends" => Ok(Extends(CounterStyleIdent::parse(input)?)),
_ => Err(ParseError::from(CustomParseError::CounterStyleSystemIsNotKnown(identifier.clone()))),
}
}
}
impl ToCss for System {
fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
use self::System::*;
match *self {
Cyclic => dest.write_str("cyclic"),
Numeric => dest.write_str("numeric"),
Alphabetic => dest.write_str("alphabetic"),
Symbolic => dest.write_str("symbolic"),
Additive => dest.write_str("additive"),
Fixed { first_symbol_value } => {
if let Some(value) = first_symbol_value {
dest.write_str("fixed ")?;
value.to_css(dest)
} else {
dest.write_str("fixed")
}
}
Extends(ref other) => {
dest.write_str("extends ")?;
other.to_css(dest)
}
}
}
}