oo_ide/input/
modifiers.rs1use 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 #[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 #[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 #[test]
180 fn default_is_empty() {
181 assert!(Modifiers::default().is_empty());
182 }
183}