sbom_tools/tui/viewmodel/
overlay.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum OverlayKind {
9 Help,
11 Export,
13 Legend,
15}
16
17#[derive(Debug, Clone, Default)]
37pub struct OverlayState {
38 current: Option<OverlayKind>,
40}
41
42impl OverlayState {
43 #[must_use]
45 pub const fn new() -> Self {
46 Self { current: None }
47 }
48
49 #[must_use]
51 pub const fn has_overlay(&self) -> bool {
52 self.current.is_some()
53 }
54
55 #[must_use]
57 pub fn is_showing(&self, kind: OverlayKind) -> bool {
58 self.current == Some(kind)
59 }
60
61 #[must_use]
63 pub const fn current(&self) -> Option<OverlayKind> {
64 self.current
65 }
66
67 pub const fn show(&mut self, kind: OverlayKind) {
69 self.current = Some(kind);
70 }
71
72 pub const fn close(&mut self) {
74 self.current = None;
75 }
76
77 pub const fn close_all(&mut self) {
79 self.current = None;
80 }
81
82 pub fn toggle(&mut self, kind: OverlayKind) {
86 if self.current == Some(kind) {
87 self.current = None;
88 } else {
89 self.current = Some(kind);
90 }
91 }
92
93 pub fn toggle_help(&mut self) {
95 self.toggle(OverlayKind::Help);
96 }
97
98 pub fn toggle_export(&mut self) {
100 self.toggle(OverlayKind::Export);
101 }
102
103 pub fn toggle_legend(&mut self) {
105 self.toggle(OverlayKind::Legend);
106 }
107
108 #[must_use]
112 pub fn show_help(&self) -> bool {
113 self.is_showing(OverlayKind::Help)
114 }
115
116 #[must_use]
118 pub fn show_export(&self) -> bool {
119 self.is_showing(OverlayKind::Export)
120 }
121
122 #[must_use]
124 pub fn show_legend(&self) -> bool {
125 self.is_showing(OverlayKind::Legend)
126 }
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn test_overlay_state_new() {
135 let state = OverlayState::new();
136 assert!(!state.has_overlay());
137 assert!(state.current().is_none());
138 }
139
140 #[test]
141 fn test_overlay_state_show() {
142 let mut state = OverlayState::new();
143
144 state.show(OverlayKind::Help);
145 assert!(state.has_overlay());
146 assert!(state.is_showing(OverlayKind::Help));
147 assert!(state.show_help());
148 assert!(!state.show_export());
149 assert!(!state.show_legend());
150 }
151
152 #[test]
153 fn test_overlay_state_mutual_exclusion() {
154 let mut state = OverlayState::new();
155
156 state.show(OverlayKind::Help);
157 assert!(state.is_showing(OverlayKind::Help));
158
159 state.show(OverlayKind::Export);
160 assert!(state.is_showing(OverlayKind::Export));
161 assert!(!state.is_showing(OverlayKind::Help));
162
163 state.show(OverlayKind::Legend);
164 assert!(state.is_showing(OverlayKind::Legend));
165 assert!(!state.is_showing(OverlayKind::Export));
166 }
167
168 #[test]
169 fn test_overlay_state_toggle() {
170 let mut state = OverlayState::new();
171
172 state.toggle(OverlayKind::Help);
174 assert!(state.is_showing(OverlayKind::Help));
175
176 state.toggle(OverlayKind::Help);
178 assert!(!state.has_overlay());
179
180 state.toggle(OverlayKind::Help);
182 state.toggle(OverlayKind::Export);
183 assert!(state.is_showing(OverlayKind::Export));
184 assert!(!state.is_showing(OverlayKind::Help));
185 }
186
187 #[test]
188 fn test_overlay_state_close() {
189 let mut state = OverlayState::new();
190
191 state.show(OverlayKind::Help);
192 assert!(state.has_overlay());
193
194 state.close();
195 assert!(!state.has_overlay());
196 }
197
198 #[test]
199 fn test_overlay_state_close_all() {
200 let mut state = OverlayState::new();
201
202 state.show(OverlayKind::Legend);
203 state.close_all();
204 assert!(!state.has_overlay());
205 }
206
207 #[test]
208 fn test_overlay_state_convenience_toggles() {
209 let mut state = OverlayState::new();
210
211 state.toggle_help();
212 assert!(state.show_help());
213
214 state.toggle_export();
215 assert!(state.show_export());
216 assert!(!state.show_help());
217
218 state.toggle_legend();
219 assert!(state.show_legend());
220 assert!(!state.show_export());
221 }
222}