1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
extern crate device_query;
extern crate eframe;
extern crate egui;
extern crate once_cell;

pub mod helper;
pub mod keycodes;
pub mod widget;

pub use keycodes::*;
pub use widget::*;

#[derive(Clone, Hash)]
pub struct KeyBind {
    pub keycode: Option<KeyCode>,
    pub modifiers: Vec<KeyModifier>,
}

impl KeyBind {
    pub fn new(keycode: Option<KeyCode>, modifiers: Vec<KeyModifier>) -> Self {
        Self { keycode, modifiers }
    }

    pub fn empty() -> Self {
        Self {
            keycode: None,
            modifiers: vec![],
        }
    }

    pub fn serialize(&mut self) -> String {
        match &self.keycode {
            Some(k) => {
                let mut prefix = String::with_capacity(self.modifiers.len());

                self.modifiers.sort();

                for modifier in &self.modifiers {
                    prefix.push(modifier.serialize());
                }

                return format!("{}{}", prefix, k.serialize());
            }

            None => "...".to_string(),
        }
    }

    pub fn deserialize(data: String) -> Result<Self, ()> {
        let mut result: Result<Self, ()> = Err(());

        let mut modifiers: Vec<KeyModifier> = vec![];

        for (i, ch) in data.chars().enumerate() {
            let deserialized_modifier = KeyModifier::deserialize(ch);

            match deserialized_modifier {
                Ok(modifier) => modifiers.push(modifier),

                Err(_) => {
                    let name_slice = &data[i..data.len()];

                    let deserialized_key = KeyCode::deserialize(name_slice.to_string());

                    match deserialized_key {
                        Ok(key) => {
                            let mods = if key.is_some() { modifiers } else { vec![] };

                            result = Ok(Self::new(key, mods));
                        }

                        _ => (),
                    }

                    break;
                }
            }
        }

        result
    }
}