livesplit_hotkey/
hotkey.rs

1use core::{fmt, str::FromStr};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{KeyCode, Modifiers};
6
7/// A hotkey is a combination of a key code and a set of modifiers.
8#[derive(Eq, PartialEq, Hash, Copy, Clone)]
9pub struct Hotkey {
10    /// The key code of the hotkey.
11    pub key_code: KeyCode,
12    /// The modifiers of the hotkey.
13    pub modifiers: Modifiers,
14}
15
16impl fmt::Debug for Hotkey {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        fmt::Display::fmt(self, f)
19    }
20}
21
22impl fmt::Display for Hotkey {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        if self.modifiers.is_empty() {
25            f.write_str(self.key_code.name())
26        } else {
27            write!(f, "{} + {}", self.modifiers, self.key_code.name())
28        }
29    }
30}
31
32impl FromStr for Hotkey {
33    type Err = ();
34
35    fn from_str(s: &str) -> Result<Self, Self::Err> {
36        if let Some((modifiers, key_code)) = s.rsplit_once('+') {
37            let modifiers = modifiers.trim_end().parse()?;
38            let key_code = key_code.trim_start().parse()?;
39            Ok(Self {
40                key_code,
41                modifiers,
42            })
43        } else {
44            let key_code = s.parse()?;
45            Ok(Self {
46                key_code,
47                modifiers: Modifiers::empty(),
48            })
49        }
50    }
51}
52
53impl Serialize for Hotkey {
54    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
55    where
56        S: serde::Serializer,
57    {
58        if self.modifiers.is_empty() {
59            self.key_code.serialize(serializer)
60        } else {
61            serializer.collect_str(self)
62        }
63    }
64}
65
66impl<'de> Deserialize<'de> for Hotkey {
67    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
68    where
69        D: serde::Deserializer<'de>,
70    {
71        deserializer.deserialize_str(HotkeyVisitor)
72    }
73}
74
75struct HotkeyVisitor;
76
77impl serde::de::Visitor<'_> for HotkeyVisitor {
78    type Value = Hotkey;
79
80    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
81        formatter.write_str("a valid hotkey")
82    }
83
84    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
85    where
86        E: serde::de::Error,
87    {
88        Hotkey::from_str(v).map_err(|()| serde::de::Error::custom("invalid hotkey"))
89    }
90}
91
92impl From<KeyCode> for Hotkey {
93    fn from(key_code: KeyCode) -> Self {
94        Self {
95            key_code,
96            modifiers: Modifiers::empty(),
97        }
98    }
99}