float_pigment_css/sheet/
keyframes.rs

1use alloc::{string::String, vec::Vec};
2
3use serde::{Deserialize, Serialize};
4
5use super::PropertyMeta;
6
7#[cfg(debug_assertions)]
8use float_pigment_css_macro::CompatibilityEnumCheck;
9
10/// A `@keyframes`` definition.
11#[allow(missing_docs)]
12#[derive(Clone, Debug)]
13pub struct KeyFrames {
14    pub ident: String,
15    pub keyframes: Vec<KeyFrameRule>,
16}
17
18impl KeyFrames {
19    pub(crate) fn new(ident: String, keyframes: Vec<KeyFrameRule>) -> Self {
20        Self { ident, keyframes }
21    }
22}
23
24impl core::fmt::Display for KeyFrames {
25    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
26        write!(f, "@keyframes {} {{ ", self.ident)?;
27        for keyframe in &self.keyframes {
28            write!(f, "{} ", keyframe)?;
29        }
30        write!(f, "}}")
31    }
32}
33
34/// The percentage field in a keyframe item.
35#[repr(C)]
36#[derive(Clone, Debug, Serialize, Deserialize)]
37#[cfg_attr(debug_assertions, derive(CompatibilityEnumCheck))]
38pub enum KeyFrame {
39    /// `from` in a keyframe.
40    From,
41    /// `to` in a keyframe.
42    To,
43    /// Percentage value in a keyframe.
44    Ratio(f32),
45}
46
47impl KeyFrame {
48    /// Get the normalized ratio (between `0.` and `1.`).
49    pub fn ratio(&self) -> f32 {
50        match self {
51            Self::From => 0.,
52            Self::To => 1.,
53            Self::Ratio(x) => *x,
54        }
55    }
56}
57
58/// A keyframe item in `@keyframes`, e.g. `50% { ... }`.
59#[allow(missing_docs)]
60#[derive(Clone, Debug)]
61pub struct KeyFrameRule {
62    pub keyframe: Vec<KeyFrame>,
63    pub properties: Vec<PropertyMeta>,
64}
65
66impl KeyFrameRule {
67    pub(crate) fn new(keyframe: Vec<KeyFrame>, properties: Vec<PropertyMeta>) -> Self {
68        Self {
69            keyframe,
70            properties,
71        }
72    }
73}
74
75impl core::fmt::Display for KeyFrameRule {
76    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77        write!(
78            f,
79            "{} {{ ",
80            self.keyframe
81                .iter()
82                .map(|x| {
83                    match x {
84                        KeyFrame::From => "from".to_owned(),
85                        KeyFrame::To => "to".to_owned(),
86                        KeyFrame::Ratio(ratio) => format!("{:.2}%", ratio * 100.),
87                    }
88                })
89                .collect::<Vec<_>>()
90                .join(", ")
91        )?;
92        for prop in &self.properties {
93            write!(
94                f,
95                "{}: {}; ",
96                prop.get_property_name(),
97                prop.get_property_value_string()
98            )?;
99        }
100        write!(f, "}}")
101    }
102}