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)]
12#[non_exhaustive]
13pub struct ThemeSpacing {
14 pub xxs: Option<f32>,
16
17 pub xs: Option<f32>,
19
20 pub s: Option<f32>,
22
23 pub m: Option<f32>,
25
26 pub l: Option<f32>,
28
29 pub xl: Option<f32>,
31
32 pub xxl: Option<f32>,
34}
35
36impl_merge!(ThemeSpacing {
37 option { xxs, xs, s, m, l, xl, xxl }
38});
39
40#[cfg(test)]
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}