native_theme/model/
spacing.rs1use serde::{Deserialize, Serialize};
4
5#[serde_with::skip_serializing_none]
10#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
11#[serde(default)]
12pub struct ThemeSpacing {
13 pub xxs: Option<f32>,
15
16 pub xs: Option<f32>,
18
19 pub s: Option<f32>,
21
22 pub m: Option<f32>,
24
25 pub l: Option<f32>,
27
28 pub xl: Option<f32>,
30
31 pub xxl: Option<f32>,
33}
34
35impl_merge!(ThemeSpacing {
36 option { xxs, xs, s, m, l, xl, xxl }
37});
38
39#[cfg(test)]
40#[allow(clippy::unwrap_used, clippy::expect_used)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn default_is_empty() {
46 assert!(ThemeSpacing::default().is_empty());
47 }
48
49 #[test]
50 fn not_empty_when_field_set() {
51 let s = ThemeSpacing {
52 m: Some(12.0),
53 ..Default::default()
54 };
55 assert!(!s.is_empty());
56 }
57
58 #[test]
59 fn merge_some_replaces_none() {
60 let mut base = ThemeSpacing::default();
61 let overlay = ThemeSpacing {
62 s: Some(8.0),
63 m: Some(12.0),
64 l: Some(16.0),
65 ..Default::default()
66 };
67 base.merge(&overlay);
68 assert_eq!(base.s, Some(8.0));
69 assert_eq!(base.m, Some(12.0));
70 assert_eq!(base.l, Some(16.0));
71 }
72
73 #[test]
74 fn merge_none_preserves_base() {
75 let mut base = ThemeSpacing {
76 xxs: Some(2.0),
77 xs: Some(4.0),
78 ..Default::default()
79 };
80 let overlay = ThemeSpacing::default();
81 base.merge(&overlay);
82 assert_eq!(base.xxs, Some(2.0));
83 assert_eq!(base.xs, Some(4.0));
84 }
85
86 #[test]
87 fn serde_toml_round_trip() {
88 let spacing = ThemeSpacing {
89 xxs: Some(2.0),
90 xs: Some(4.0),
91 s: Some(8.0),
92 m: Some(12.0),
93 l: Some(16.0),
94 xl: Some(24.0),
95 xxl: Some(32.0),
96 };
97 let toml_str = toml::to_string(&spacing).unwrap();
98 let deserialized: ThemeSpacing = toml::from_str(&toml_str).unwrap();
99 assert_eq!(deserialized, spacing);
100 }
101}