native_theme/model/
geometry.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 ThemeGeometry {
14 pub radius: Option<f32>,
16
17 pub radius_lg: Option<f32>,
19
20 pub frame_width: Option<f32>,
22
23 pub disabled_opacity: Option<f32>,
25
26 pub border_opacity: Option<f32>,
28
29 pub scroll_width: Option<f32>,
31
32 pub shadow: Option<bool>,
34}
35
36impl_merge!(ThemeGeometry {
37 option { radius, radius_lg, frame_width, disabled_opacity, border_opacity, scroll_width, shadow }
38});
39
40#[cfg(test)]
41mod tests {
42 use super::*;
43
44 #[test]
45 fn default_is_empty() {
46 assert!(ThemeGeometry::default().is_empty());
47 }
48
49 #[test]
50 fn not_empty_when_field_set() {
51 let g = ThemeGeometry {
52 radius: Some(4.0),
53 ..Default::default()
54 };
55 assert!(!g.is_empty());
56 }
57
58 #[test]
59 fn merge_some_replaces_none() {
60 let mut base = ThemeGeometry::default();
61 let overlay = ThemeGeometry {
62 radius: Some(8.0),
63 frame_width: Some(1.0),
64 ..Default::default()
65 };
66 base.merge(&overlay);
67 assert_eq!(base.radius, Some(8.0));
68 assert_eq!(base.frame_width, Some(1.0));
69 }
70
71 #[test]
72 fn merge_none_preserves_base() {
73 let mut base = ThemeGeometry {
74 radius: Some(4.0),
75 disabled_opacity: Some(0.5),
76 ..Default::default()
77 };
78 let overlay = ThemeGeometry::default();
79 base.merge(&overlay);
80 assert_eq!(base.radius, Some(4.0));
81 assert_eq!(base.disabled_opacity, Some(0.5));
82 }
83
84 #[test]
85 fn serde_toml_round_trip() {
86 let geom = ThemeGeometry {
87 radius: Some(8.0),
88 radius_lg: Some(12.0),
89 frame_width: Some(1.0),
90 disabled_opacity: Some(0.4),
91 border_opacity: Some(0.6),
92 scroll_width: Some(12.0),
93 shadow: Some(true),
94 };
95 let toml_str = toml::to_string(&geom).unwrap();
96 let deserialized: ThemeGeometry = toml::from_str(&toml_str).unwrap();
97 assert_eq!(deserialized, geom);
98 }
99
100 #[test]
101 fn new_fields_default_to_none() {
102 let g = ThemeGeometry::default();
103 assert!(g.radius_lg.is_none());
104 assert!(g.shadow.is_none());
105 }
106
107 #[test]
108 fn merge_new_fields() {
109 let mut base = ThemeGeometry::default();
110 let overlay = ThemeGeometry {
111 radius_lg: Some(16.0),
112 shadow: Some(true),
113 ..Default::default()
114 };
115 base.merge(&overlay);
116 assert_eq!(base.radius_lg, Some(16.0));
117 assert_eq!(base.shadow, Some(true));
118
119 let mut base2 = ThemeGeometry {
121 radius_lg: Some(12.0),
122 shadow: Some(false),
123 ..Default::default()
124 };
125 let overlay2 = ThemeGeometry::default();
126 base2.merge(&overlay2);
127 assert_eq!(base2.radius_lg, Some(12.0));
128 assert_eq!(base2.shadow, Some(false));
129 }
130}