takumi_css/style/properties/
font_style.rs1use std::fmt;
2
3use crate::style::{ToCss, unexpected_token};
4use cssparser::{Parser, Token, match_ignore_ascii_case};
5use parley::style::FontStyle as ParleyFontStyle;
6
7use crate::style::{Angle, CssToken, FromCss, MakeComputed, ParseResult};
8
9#[derive(Default, Debug, Clone, Copy, PartialEq)]
11pub struct FontStyle(ParleyFontStyle);
12
13impl MakeComputed for FontStyle {}
14
15impl<'i> FromCss<'i> for FontStyle {
16 fn from_css(input: &mut Parser<'i, '_>) -> ParseResult<'i, Self> {
17 let location = input.current_source_location();
18 let ident = input.expect_ident()?;
19
20 match_ignore_ascii_case! { ident,
21 "normal" => Ok(Self(ParleyFontStyle::Normal)),
22 "italic" => Ok(Self(ParleyFontStyle::Italic)),
23 "oblique" => {
24 let angle = input.try_parse(Angle::from_css).ok().map(|angle| *angle);
25 Ok(Self(ParleyFontStyle::Oblique(angle)))
26 },
27 _ => Err(unexpected_token!(location, &Token::Ident(ident.to_owned()))),
28 }
29 }
30
31 const VALID_TOKENS: &'static [CssToken] = &[
32 CssToken::Keyword("normal"),
33 CssToken::Keyword("italic"),
34 CssToken::Keyword("oblique"),
35 ];
36}
37
38impl FontStyle {
39 pub const fn normal() -> Self {
41 Self(ParleyFontStyle::Normal)
42 }
43
44 pub const fn italic() -> Self {
46 Self(ParleyFontStyle::Italic)
47 }
48
49 pub const fn oblique(angle: f32) -> Self {
51 Self(ParleyFontStyle::Oblique(Some(angle)))
52 }
53}
54
55impl From<FontStyle> for ParleyFontStyle {
56 fn from(value: FontStyle) -> Self {
57 value.0
58 }
59}
60
61impl ToCss for FontStyle {
62 fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
63 match &self.0 {
64 ParleyFontStyle::Normal => dest.write_str("normal"),
65 ParleyFontStyle::Italic => dest.write_str("italic"),
66 ParleyFontStyle::Oblique(angle) => match angle {
67 Some(a) => write!(dest, "oblique {}deg", a),
68 None => dest.write_str("oblique"),
69 },
70 }
71 }
72}