Skip to main content

recovery_ui/
keys.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#[derive(PartialEq, Debug, Clone)]
6pub struct LetterKey {
7    pub(crate) lower: &'static str,
8    pub(crate) upper: &'static str,
9    pub(crate) alt: &'static str,
10    #[allow(unused)]
11    pub(crate) is_alt_accent: bool,
12}
13
14#[derive(PartialEq, Debug, Clone)]
15pub enum SpecialKey {
16    ALT,
17    DEL,
18    ENTER,
19    SHIFT,
20    SPACE,
21}
22
23#[derive(PartialEq, Debug, Clone)]
24pub enum Key {
25    Letter(LetterKey),
26    Special(SpecialKey, &'static str),
27}
28
29const DEFAULT_KEY: LetterKey = LetterKey { lower: "", upper: "", alt: "", is_alt_accent: false };
30
31const KEY_A: Key = Key::Letter(LetterKey { lower: "a", upper: "A", alt: "æ", ..DEFAULT_KEY });
32const KEY_B: Key = Key::Letter(LetterKey { lower: "b", upper: "B", ..DEFAULT_KEY });
33const KEY_C: Key = Key::Letter(LetterKey { lower: "c", upper: "C", alt: "ç", ..DEFAULT_KEY });
34const KEY_D: Key = Key::Letter(LetterKey { lower: "d", upper: "D", alt: "∂", ..DEFAULT_KEY });
35const KEY_E: Key =
36    Key::Letter(LetterKey {
37        lower: "e", upper: "E", alt: "´", is_alt_accent: true, ..DEFAULT_KEY
38    });
39const KEY_F: Key = Key::Letter(LetterKey { lower: "f", upper: "F", alt: "ƒ", ..DEFAULT_KEY });
40const KEY_G: Key = Key::Letter(LetterKey { lower: "g", upper: "G", alt: "©", ..DEFAULT_KEY });
41const KEY_H: Key = Key::Letter(LetterKey { lower: "h", upper: "H", ..DEFAULT_KEY });
42const KEY_I: Key =
43    Key::Letter(LetterKey {
44        lower: "i", upper: "I", alt: "ˆ", is_alt_accent: true, ..DEFAULT_KEY
45    });
46const KEY_J: Key = Key::Letter(LetterKey { lower: "j", upper: "J", ..DEFAULT_KEY });
47const KEY_K: Key =
48    Key::Letter(LetterKey {
49        lower: "k", upper: "K", alt: "˚", is_alt_accent: true, ..DEFAULT_KEY
50    });
51const KEY_L: Key = Key::Letter(LetterKey { lower: "l", upper: "L", ..DEFAULT_KEY });
52const KEY_M: Key = Key::Letter(LetterKey { lower: "m", upper: "M", ..DEFAULT_KEY });
53const KEY_N: Key =
54    Key::Letter(LetterKey {
55        lower: "n", upper: "N", alt: "˜", is_alt_accent: true, ..DEFAULT_KEY
56    });
57const KEY_O: Key = Key::Letter(LetterKey { lower: "o", upper: "O", alt: "ø", ..DEFAULT_KEY });
58const KEY_P: Key = Key::Letter(LetterKey { lower: "p", upper: "P", alt: "Ø", ..DEFAULT_KEY });
59const KEY_Q: Key = Key::Letter(LetterKey { lower: "q", upper: "Q", alt: "œ", ..DEFAULT_KEY });
60const KEY_R: Key = Key::Letter(LetterKey { lower: "r", upper: "R", alt: "®", ..DEFAULT_KEY });
61const KEY_S: Key = Key::Letter(LetterKey { lower: "s", upper: "S", alt: "ß", ..DEFAULT_KEY });
62const KEY_T: Key = Key::Letter(LetterKey { lower: "t", upper: "T", ..DEFAULT_KEY });
63const KEY_U: Key =
64    Key::Letter(LetterKey {
65        lower: "u", upper: "U", alt: "¨", is_alt_accent: true, ..DEFAULT_KEY
66    });
67const KEY_V: Key = Key::Letter(LetterKey { lower: "v", upper: "V", ..DEFAULT_KEY });
68const KEY_W: Key = Key::Letter(LetterKey { lower: "w", upper: "W", alt: "Œ", ..DEFAULT_KEY });
69const KEY_X: Key = Key::Letter(LetterKey { lower: "x", upper: "X", alt: "Ç", ..DEFAULT_KEY });
70const KEY_Y: Key = Key::Letter(LetterKey { lower: "y", upper: "Y", alt: "¥", ..DEFAULT_KEY });
71const KEY_Z: Key = Key::Letter(LetterKey { lower: "z", upper: "Z", alt: "Æ", ..DEFAULT_KEY });
72const KEY_0: Key = Key::Letter(LetterKey { lower: "0", upper: ")", alt: "º", ..DEFAULT_KEY });
73const KEY_1: Key = Key::Letter(LetterKey { lower: "1", upper: "!", alt: "¡", ..DEFAULT_KEY });
74const KEY_2: Key = Key::Letter(LetterKey { lower: "2", upper: "@", alt: "€", ..DEFAULT_KEY });
75const KEY_3: Key = Key::Letter(LetterKey { lower: "3", upper: "#", alt: "£", ..DEFAULT_KEY });
76const KEY_4: Key = Key::Letter(LetterKey { lower: "4", upper: "$", alt: "¢", ..DEFAULT_KEY });
77const KEY_5: Key = Key::Letter(LetterKey { lower: "5", upper: "%", alt: "∞", ..DEFAULT_KEY });
78const KEY_6: Key = Key::Letter(LetterKey { lower: "6", upper: "^", alt: "§", ..DEFAULT_KEY });
79const KEY_7: Key = Key::Letter(LetterKey { lower: "7", upper: "&", alt: "¶", ..DEFAULT_KEY });
80const KEY_8: Key = Key::Letter(LetterKey { lower: "8", upper: "*", alt: "•", ..DEFAULT_KEY });
81const KEY_9: Key = Key::Letter(LetterKey { lower: "9", upper: "(", alt: "ª", ..DEFAULT_KEY });
82const KEY_BACK_TICK: Key =
83    Key::Letter(LetterKey { lower: "`", upper: "~", alt: "`", is_alt_accent: true, ..DEFAULT_KEY });
84const KEY_HYPHEN: Key = Key::Letter(LetterKey { lower: "-", upper: "_", alt: "±", ..DEFAULT_KEY });
85const KEY_EQUALS: Key =
86    Key::Letter(LetterKey { lower: "=", upper: "+", alt: "≠", ..DEFAULT_KEY });
87const KEY_L_BRACKET: Key = Key::Letter(LetterKey { lower: "[", upper: "{", ..DEFAULT_KEY });
88const KEY_R_BRACKET: Key = Key::Letter(LetterKey { lower: "]", upper: "}", ..DEFAULT_KEY });
89const KEY_BACKSLASH: Key = Key::Letter(LetterKey { lower: "\\", upper: "|", ..DEFAULT_KEY });
90const KEY_SEMICOLON: Key = Key::Letter(LetterKey { lower: ";", upper: ":", ..DEFAULT_KEY });
91const KEY_QUOTE: Key = Key::Letter(LetterKey { lower: "'", upper: "\"", ..DEFAULT_KEY });
92const KEY_COMMA: Key = Key::Letter(LetterKey { lower: ",", upper: "<", ..DEFAULT_KEY });
93const KEY_FULL_STOP: Key = Key::Letter(LetterKey { lower: ".", upper: ">", ..DEFAULT_KEY });
94const KEY_SLASH: Key = Key::Letter(LetterKey { lower: "/", upper: "?", ..DEFAULT_KEY });
95
96const KEY_ALT: Key = Key::Special(SpecialKey::ALT, "alt");
97const KEY_DEL: Key = Key::Special(SpecialKey::DEL, "del");
98const KEY_ENTER: Key = Key::Special(SpecialKey::ENTER, "enter");
99const KEY_SHIFT: Key = Key::Special(SpecialKey::SHIFT, "shift");
100const KEY_SPACE: Key = Key::Special(SpecialKey::SPACE, "space");
101
102pub(crate) const ROW0: &'static [&Key] = &[
103    &KEY_BACK_TICK,
104    &KEY_1,
105    &KEY_2,
106    &KEY_3,
107    &KEY_4,
108    &KEY_5,
109    &KEY_6,
110    &KEY_7,
111    &KEY_8,
112    &KEY_9,
113    &KEY_0,
114    &KEY_HYPHEN,
115    &KEY_EQUALS,
116];
117
118pub(crate) const ROW1: &'static [&Key] = &[
119    &KEY_Q,
120    &KEY_W,
121    &KEY_E,
122    &KEY_R,
123    &KEY_T,
124    &KEY_Y,
125    &KEY_U,
126    &KEY_I,
127    &KEY_O,
128    &KEY_P,
129    &KEY_L_BRACKET,
130    &KEY_R_BRACKET,
131    &KEY_BACKSLASH,
132];
133
134const ROW2: &'static [&Key] = &[
135    &KEY_A,
136    &KEY_S,
137    &KEY_D,
138    &KEY_F,
139    &KEY_G,
140    &KEY_H,
141    &KEY_J,
142    &KEY_K,
143    &KEY_L,
144    &KEY_SEMICOLON,
145    &KEY_QUOTE,
146];
147
148const ROW3: &'static [&Key] = &[
149    &KEY_Z,
150    &KEY_X,
151    &KEY_C,
152    &KEY_V,
153    &KEY_B,
154    &KEY_N,
155    &KEY_M,
156    &KEY_COMMA,
157    &KEY_FULL_STOP,
158    &KEY_SLASH,
159];
160const SPECIAL_ROW: &'static [&Key] = &[&KEY_SHIFT, &KEY_ALT, &KEY_SPACE, &KEY_DEL, &KEY_ENTER];
161
162pub const KEYBOARD: &'static [&'static [&Key]] = &[ROW0, ROW1, ROW2, ROW3, SPECIAL_ROW];
163
164#[derive(Debug, PartialEq)]
165pub struct Accent {
166    accent: &'static Key,
167    pub(crate) lower: &'static str,
168    pub(crate) upper: &'static str,
169}
170
171#[derive(Debug, PartialEq)]
172pub struct AccentKey {
173    pub alt_key: &'static Key,
174    accents: &'static [&'static Accent],
175}
176
177const ACCENT_GRAVE: AccentKey = AccentKey {
178    alt_key: &KEY_BACK_TICK,
179    accents: &[
180        &Accent { accent: &KEY_A, lower: "à", upper: "À" },
181        &Accent { accent: &KEY_E, lower: "è", upper: "È" },
182        &Accent { accent: &KEY_I, lower: "ì", upper: "Ì" },
183        &Accent { accent: &KEY_O, lower: "ò", upper: "Ò" },
184        &Accent { accent: &KEY_U, lower: "ù", upper: "Ù" },
185    ],
186};
187
188const ACCENT_ACUTE: AccentKey = AccentKey {
189    alt_key: &KEY_E,
190    accents: &[
191        &Accent { accent: &KEY_A, lower: "á", upper: "Á" },
192        &Accent { accent: &KEY_E, lower: "é", upper: "É" },
193        &Accent { accent: &KEY_I, lower: "í", upper: "Í" },
194        &Accent { accent: &KEY_O, lower: "ó", upper: "Ó" },
195        &Accent { accent: &KEY_U, lower: "ú", upper: "Ú" },
196    ],
197};
198
199const ACCENT_RING: AccentKey =
200    AccentKey { alt_key: &KEY_K, accents: &[&Accent { accent: &KEY_A, lower: "å", upper: "Å" }] };
201
202const ACCENT_UMLAUT: AccentKey = AccentKey {
203    alt_key: &KEY_U,
204    accents: &[
205        &Accent { accent: &KEY_A, lower: "ä", upper: "Ä" },
206        &Accent { accent: &KEY_E, lower: "ë", upper: "Ë" },
207        &Accent { accent: &KEY_I, lower: "ï", upper: "Ï" },
208        &Accent { accent: &KEY_O, lower: "ö", upper: "Ö" },
209        &Accent { accent: &KEY_U, lower: "ü", upper: "ü" },
210    ],
211};
212
213const ACCENT_CIRCUMFLEX: AccentKey = AccentKey {
214    alt_key: &KEY_I,
215    accents: &[
216        &Accent { accent: &KEY_A, lower: "â", upper: "Â" },
217        &Accent { accent: &KEY_E, lower: "ê", upper: "Ê" },
218        &Accent { accent: &KEY_I, lower: "î", upper: "Î" },
219        &Accent { accent: &KEY_O, lower: "ô", upper: "Ô" },
220        &Accent { accent: &KEY_U, lower: "û", upper: "Û" },
221    ],
222};
223
224const ACCENT_TILDE: AccentKey = AccentKey {
225    alt_key: &KEY_N,
226    accents: &[
227        &Accent { accent: &KEY_A, lower: "ã", upper: "Ã" },
228        &Accent { accent: &KEY_N, lower: "ñ", upper: "Ñ" },
229        &Accent { accent: &KEY_O, lower: "õ", upper: "Õ	" },
230    ],
231};
232
233pub const ACCENTS: &'static [AccentKey] =
234    &[ACCENT_GRAVE, ACCENT_CIRCUMFLEX, ACCENT_ACUTE, ACCENT_RING, ACCENT_UMLAUT, ACCENT_TILDE];
235
236pub fn get_accent(alt_key: &Key, pressed_key: &Key) -> Option<&'static &'static Accent> {
237    if let Some(accent_key) = ACCENTS.iter().find(|ak| ak.alt_key == alt_key) {
238        return accent_key.accents.iter().find(|a| a.accent == pressed_key);
239    };
240    None
241}
242
243#[cfg(test)]
244mod test {
245
246    use crate::keys::*;
247
248    #[test]
249    fn get_accent() {
250        assert_eq!(
251            super::get_accent(&KEY_E, &KEY_E),
252            Some(&&Accent { accent: &KEY_E, lower: "é", upper: "É" })
253        );
254    }
255
256    #[test]
257    fn get_non_accent() {
258        assert_eq!(super::get_accent(&KEY_P, &KEY_E), None);
259    }
260}