diff --git a/crates/hdx_ast/src/css/values/fonts/mod.rs b/crates/hdx_ast/src/css/values/fonts/mod.rs index b9909db4..f9268009 100644 --- a/crates/hdx_ast/src/css/values/fonts/mod.rs +++ b/crates/hdx_ast/src/css/values/fonts/mod.rs @@ -19,14 +19,14 @@ use impls::*; // pub enum FontFamilyStyleValue<'a> {} // // https://drafts.csswg.org/css-fonts-5/#font-weight -// #[value(" | bolder | lighter ")] -// #[initial("normal")] -// #[applies_to("all elements and text")] -// #[inherited("yes")] -// #[percentages("n/a")] -// #[canonical_order("per grammar")] -// #[animation_type("by computed value type")] -// pub enum FontWeightStyleValue {} +#[value(" | bolder | lighter ")] +#[initial("normal")] +#[applies_to("all elements and text")] +#[inherited("yes")] +#[percentages("n/a")] +#[canonical_order("per grammar")] +#[animation_type("by computed value type")] +pub enum FontWeightStyleValue {} // https://drafts.csswg.org/css-fonts-5/#font-width #[value(" normal | | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded ")] diff --git a/crates/hdx_ast/src/css/values/fonts/types.rs b/crates/hdx_ast/src/css/values/fonts/types.rs index da6b8c64..4558b293 100644 --- a/crates/hdx_ast/src/css/values/fonts/types.rs +++ b/crates/hdx_ast/src/css/values/fonts/types.rs @@ -1 +1,79 @@ -pub(crate) use crate::css::units::*; +use hdx_atom::atom; +use hdx_lexer::Cursor; +use hdx_parser::{diagnostics, Build, CursorStream, Parse, Parser, Peek, Result as ParserResult, ToCursors, T}; + +mod func { + use hdx_parser::custom_keyword; + custom_keyword!(Normal, atom!("normal")); + custom_keyword!(Bold, atom!("bold")); + custom_keyword!(Bolder, atom!("bolder")); + custom_keyword!(Lighter, atom!("lighter")); +} + +// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight +// = [normal | bold | ] +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize), serde(rename_all = "kebab-case"))] +pub enum FontWeightAbsolute { + Normal(T![Ident]), + Bold(T![Ident]), + Bolder(T![Ident]), + Lighter(T![Ident]), +} + +impl<'a> Peek<'a> for FontWeightAbsolute { + fn peek(p: &Parser<'a>) -> bool { + p.peek::() + || p.peek::() + || p.peek::() + || p.peek::() + || p.peek::() + } +} + +impl<'a> Parse<'a> for FontWeightAbsolute { + fn parse(p: &mut Parser<'a>) -> ParserResult { + let ident = p.parse::()?; + let c: Cursor = ident.into(); + match p.parse_atom_lower(c) { + atom!("normal") => Ok(Self::Normal(::build(p, c))), + atom!("bold") => Ok(Self::Bold(::build(p, c))), + atom!("bolder") => Ok(Self::Bolder(::build(p, c))), + atom!("lighter") => Ok(Self::Lighter(::build(p, c))), + atom => Err(diagnostics::UnexpectedIdent(atom, c.into()))?, + } + } +} + +impl<'a> ToCursors<'a> for FontWeightAbsolute { + fn to_cursors(&self, s: &mut CursorStream<'a>) { + match self { + Self::Normal(c) => s.append(c.into()), + Self::Bold(c) => s.append(c.into()), + Self::Bolder(c) => s.append(c.into()), + Self::Lighter(c) => s.append(c.into()), + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_helpers::*; + + #[test] + fn size_test() { + assert_size!(FontWeightAbsolute, 56); + } + + #[test] + fn test_writes() { + assert_parse!(FontWeightAbsolute, "normal"); + assert_parse!(FontWeightAbsolute, "bold"); + assert_parse!(FontWeightAbsolute, "bolder"); + assert_parse!(FontWeightAbsolute, "lighter"); + assert_parse!(FontWeightAbsolute, "100"); + assert_parse!(FontWeightAbsolute, "500"); + assert_parse!(FontWeightAbsolute, "900"); + } +}