native_theme/model/
icon_sizes.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 IconSizes {
14 pub toolbar: Option<f32>,
16 pub small: Option<f32>,
18 pub large: Option<f32>,
20 pub dialog: Option<f32>,
22 pub panel: Option<f32>,
24}
25
26impl_merge!(IconSizes {
27 option { toolbar, small, large, dialog, panel }
28});
29
30#[cfg(test)]
31#[allow(clippy::unwrap_used, clippy::expect_used)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn icon_sizes_default_is_empty() {
37 assert!(IconSizes::default().is_empty());
38 }
39
40 #[test]
41 fn icon_sizes_not_empty_when_toolbar_set() {
42 let s = IconSizes {
43 toolbar: Some(24.0),
44 ..Default::default()
45 };
46 assert!(!s.is_empty());
47 }
48
49 #[test]
50 fn icon_sizes_not_empty_when_any_field_set() {
51 for sizes in [
52 IconSizes {
53 toolbar: Some(24.0),
54 ..Default::default()
55 },
56 IconSizes {
57 small: Some(16.0),
58 ..Default::default()
59 },
60 IconSizes {
61 large: Some(32.0),
62 ..Default::default()
63 },
64 IconSizes {
65 dialog: Some(22.0),
66 ..Default::default()
67 },
68 IconSizes {
69 panel: Some(20.0),
70 ..Default::default()
71 },
72 ] {
73 assert!(!sizes.is_empty());
74 }
75 }
76
77 #[test]
78 fn icon_sizes_merge_overlay_wins() {
79 let mut base = IconSizes {
80 toolbar: Some(24.0),
81 small: Some(16.0),
82 large: None,
83 dialog: None,
84 panel: None,
85 };
86 let overlay = IconSizes {
87 toolbar: None,
88 small: Some(18.0),
89 large: Some(32.0),
90 dialog: None,
91 panel: None,
92 };
93 base.merge(&overlay);
94 assert_eq!(base.toolbar, Some(24.0)); assert_eq!(base.small, Some(18.0)); assert_eq!(base.large, Some(32.0)); assert_eq!(base.dialog, None);
98 assert_eq!(base.panel, None);
99 }
100
101 #[test]
102 fn icon_sizes_merge_none_preserves_base() {
103 let mut base = IconSizes {
104 toolbar: Some(24.0),
105 small: Some(16.0),
106 large: Some(32.0),
107 dialog: Some(22.0),
108 panel: Some(20.0),
109 };
110 let overlay = IconSizes::default();
111 base.merge(&overlay);
112 assert_eq!(base.toolbar, Some(24.0));
113 assert_eq!(base.small, Some(16.0));
114 assert_eq!(base.large, Some(32.0));
115 assert_eq!(base.dialog, Some(22.0));
116 assert_eq!(base.panel, Some(20.0));
117 }
118
119 #[test]
120 fn icon_sizes_toml_round_trip() {
121 let sizes = IconSizes {
122 toolbar: Some(24.0),
123 small: Some(16.0),
124 large: Some(32.0),
125 dialog: Some(22.0),
126 panel: Some(20.0),
127 };
128 let toml_str = toml::to_string(&sizes).unwrap();
129 let deserialized: IconSizes = toml::from_str(&toml_str).unwrap();
130 assert_eq!(deserialized, sizes);
131 }
132
133 #[test]
134 fn icon_sizes_toml_partial_round_trip() {
135 let sizes = IconSizes {
136 toolbar: Some(24.0),
137 ..Default::default()
138 };
139 let toml_str = toml::to_string(&sizes).unwrap();
140 let deserialized: IconSizes = toml::from_str(&toml_str).unwrap();
141 assert_eq!(deserialized, sizes);
142 assert!(deserialized.small.is_none());
143 }
144}