Skip to main content

oo_ide/input/
modifiers.rs

1use std::fmt;
2
3use bitflags::bitflags;
4
5bitflags! {
6    #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
7    pub struct Modifiers: u8 {
8        const CTRL  = 0b0001;
9        const ALT   = 0b0010;
10        const SHIFT = 0b0100;
11    }
12}
13
14use crossterm::event::KeyModifiers;
15
16impl From<KeyModifiers> for Modifiers {
17    fn from(value: KeyModifiers) -> Self {
18        let mut mods = Modifiers::empty();
19
20        if value.contains(KeyModifiers::CONTROL) {
21            mods |= Modifiers::CTRL;
22        }
23
24        if value.contains(KeyModifiers::ALT) {
25            mods |= Modifiers::ALT;
26        }
27
28        if value.contains(KeyModifiers::SHIFT) {
29            mods |= Modifiers::SHIFT;
30        }
31
32        mods
33    }
34}
35
36impl fmt::Display for Modifiers {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        let mut first = true;
39
40        if self.contains(Modifiers::CTRL) {
41            write!(f, "Ctrl")?;
42            first = false;
43        }
44
45        if self.contains(Modifiers::ALT) {
46            if !first {
47                write!(f, "+")?;
48            }
49            write!(f, "Alt")?;
50            first = false;
51        }
52
53        if self.contains(Modifiers::SHIFT) {
54            if !first {
55                write!(f, "+")?;
56            }
57            write!(f, "Shift")?;
58        }
59
60        Ok(())
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67
68    // --- From<KeyModifiers> ---
69    #[test]
70    fn from_empty() {
71        assert!(Modifiers::from(KeyModifiers::empty()).is_empty());
72    }
73
74    #[test]
75    fn from_ctrl() {
76        assert!(Modifiers::from(KeyModifiers::CONTROL).contains(Modifiers::CTRL));
77    }
78
79    #[test]
80    fn from_alt() {
81        assert!(Modifiers::from(KeyModifiers::ALT).contains(Modifiers::ALT));
82    }
83
84    #[test]
85    fn from_shift() {
86        assert!(Modifiers::from(KeyModifiers::SHIFT).contains(Modifiers::SHIFT));
87    }
88
89    #[test]
90    fn from_ctrl_does_not_set_alt_or_shift() {
91        let m = Modifiers::from(KeyModifiers::CONTROL);
92        assert!(!m.contains(Modifiers::ALT));
93        assert!(!m.contains(Modifiers::SHIFT));
94    }
95
96    #[test]
97    fn from_ctrl_alt() {
98        let m = Modifiers::from(KeyModifiers::CONTROL | KeyModifiers::ALT);
99        assert!(m.contains(Modifiers::CTRL));
100        assert!(m.contains(Modifiers::ALT));
101        assert!(!m.contains(Modifiers::SHIFT));
102    }
103
104    #[test]
105    fn from_ctrl_shift() {
106        let m = Modifiers::from(KeyModifiers::CONTROL | KeyModifiers::SHIFT);
107        assert!(m.contains(Modifiers::CTRL));
108        assert!(!m.contains(Modifiers::ALT));
109        assert!(m.contains(Modifiers::SHIFT));
110    }
111
112    #[test]
113    fn from_alt_shift() {
114        let m = Modifiers::from(KeyModifiers::ALT | KeyModifiers::SHIFT);
115        assert!(!m.contains(Modifiers::CTRL));
116        assert!(m.contains(Modifiers::ALT));
117        assert!(m.contains(Modifiers::SHIFT));
118    }
119
120    #[test]
121    fn from_all() {
122        let m = Modifiers::from(KeyModifiers::CONTROL | KeyModifiers::ALT | KeyModifiers::SHIFT);
123        assert!(m.contains(Modifiers::CTRL));
124        assert!(m.contains(Modifiers::ALT));
125        assert!(m.contains(Modifiers::SHIFT));
126    }
127
128    // --- Display ---
129    #[test]
130    fn display_empty() {
131        assert_eq!(Modifiers::empty().to_string(), "");
132    }
133
134    #[test]
135    fn display_ctrl() {
136        assert_eq!(Modifiers::CTRL.to_string(), "Ctrl");
137    }
138
139    #[test]
140    fn display_alt() {
141        assert_eq!(Modifiers::ALT.to_string(), "Alt");
142    }
143
144    #[test]
145    fn display_shift() {
146        assert_eq!(Modifiers::SHIFT.to_string(), "Shift");
147    }
148
149    #[test]
150    fn display_ctrl_alt() {
151        assert_eq!((Modifiers::CTRL | Modifiers::ALT).to_string(), "Ctrl+Alt");
152    }
153
154    #[test]
155    fn display_ctrl_shift() {
156        assert_eq!(
157            (Modifiers::CTRL | Modifiers::SHIFT).to_string(),
158            "Ctrl+Shift"
159        );
160    }
161
162    #[test]
163    fn display_alt_shift() {
164        assert_eq!(
165            (Modifiers::ALT | Modifiers::SHIFT).to_string(),
166            "Alt+Shift"
167        );
168    }
169
170    #[test]
171    fn display_all() {
172        assert_eq!(
173            (Modifiers::CTRL | Modifiers::ALT | Modifiers::SHIFT).to_string(),
174            "Ctrl+Alt+Shift"
175        );
176    }
177
178    // --- Default ---
179    #[test]
180    fn default_is_empty() {
181        assert!(Modifiers::default().is_empty());
182    }
183}