float_pigment_css/sheet/
font_face.rs

1use alloc::{string::String, vec::Vec};
2
3use crate::typing::{FontFamilyName, FontStyleType, FontWeightType};
4#[cfg(debug_assertions)]
5use float_pigment_css_macro::CompatibilityEnumCheck;
6
7/// A `@font-face`` definition.
8#[allow(missing_docs)]
9#[derive(Debug, Clone, PartialEq)]
10pub struct FontFace {
11    pub font_family: FontFamilyName, // required
12    pub src: Vec<FontSrc>,           // required
13    pub font_style: Option<FontStyleType>,
14    pub font_weight: Option<FontWeightType>,
15    pub font_display: Option<FontDisplay>,
16}
17
18impl core::fmt::Display for FontFace {
19    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
20        write!(f, "@font-face {{")?;
21        write!(f, " font-family: {};", self.font_family)?;
22        write!(f, " src: ")?;
23        for src in &self.src {
24            write!(f, "{}, ", src)?;
25        }
26        write!(f, ";")?;
27        if let Some(fs) = &self.font_style {
28            write!(f, " font-style: {};", fs)?;
29        }
30        if let Some(fw) = &self.font_weight {
31            write!(f, " font-weight: {};", fw)?;
32        }
33        if let Some(fd) = &self.font_display {
34            write!(f, " font-display: {};", fd)?;
35        }
36        write!(f, "}}")
37    }
38}
39
40#[allow(missing_docs)]
41#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
42pub enum FontSrc {
43    Local(FontFamilyName),
44    Url(FontUrl),
45}
46
47impl core::fmt::Display for FontSrc {
48    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
49        match self {
50            Self::Local(ff) => write!(f, r#"local("{}")"#, ff),
51            Self::Url(url) => {
52                write!(f, r#"url("{}")"#, url.url)?;
53                if let Some(formats) = &url.format {
54                    for format in formats {
55                        write!(f, r#" format("{}")"#, format)?;
56                    }
57                }
58                Ok(())
59            }
60        }
61    }
62}
63
64#[allow(missing_docs)]
65#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
66pub struct FontUrl {
67    pub url: String,
68    pub format: Option<Vec<String>>,
69}
70
71#[allow(missing_docs)]
72#[repr(C)]
73#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
74#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
75pub enum FontDisplay {
76    Auto,
77    Block,
78    Swap,
79    Fallback,
80    Optional,
81}
82
83impl core::fmt::Display for FontDisplay {
84    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
85        match self {
86            Self::Auto => write!(f, "auto"),
87            Self::Block => write!(f, "block"),
88            Self::Swap => write!(f, "swap"),
89            Self::Fallback => write!(f, "fallback"),
90            Self::Optional => write!(f, "optional"),
91        }
92    }
93}
94
95impl Default for FontFace {
96    fn default() -> Self {
97        Self {
98            font_family: FontFamilyName::Serif,
99            src: vec![],
100            font_style: None,
101            font_weight: None,
102            font_display: None,
103        }
104    }
105}
106
107impl FontFace {
108    /// Create an empty font-face definition.
109    pub fn new() -> Self {
110        Self::default()
111    }
112
113    /// Set the family name.
114    pub fn with_font_family(&mut self, ff: FontFamilyName) -> &mut Self {
115        self.font_family = ff;
116        self
117    }
118
119    /// Set the `src` URL.
120    pub fn with_src(&mut self, src: Vec<FontSrc>) -> &mut Self {
121        self.src = src;
122        self
123    }
124
125    /// Set the `font-style`.
126    pub fn with_font_style(&mut self, fs: Option<FontStyleType>) -> &mut Self {
127        self.font_style = fs;
128        self
129    }
130
131    /// Set the `font-weight`.
132    pub fn with_font_weight(&mut self, fw: Option<FontWeightType>) -> &mut Self {
133        self.font_weight = fw;
134        self
135    }
136
137    /// Set the `font-display`.
138    pub fn with_font_display(&mut self, fd: Option<FontDisplay>) -> &mut Self {
139        self.font_display = fd;
140        self
141    }
142}