livesplit_hotkey/
modifiers.rs1use core::{fmt, str::FromStr};
2
3use serde::{Deserialize, Serialize};
4
5bitflags::bitflags! {
6 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
8 pub struct Modifiers: u8 {
9 const SHIFT = 1 << 0;
11 const CONTROL = 1 << 1;
13 const ALT = 1 << 2;
15 const META = 1 << 3;
17 }
18}
19
20impl fmt::Display for Modifiers {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 let mut first = true;
23 if self.contains(Modifiers::CONTROL) {
24 first = false;
25 f.write_str("Ctrl")?;
26 }
27 if self.contains(Modifiers::ALT) {
28 if !first {
29 f.write_str(" + ")?;
30 }
31 first = false;
32 f.write_str("Alt")?;
33 }
34 if self.contains(Modifiers::META) {
35 if !first {
36 f.write_str(" + ")?;
37 }
38 first = false;
39 f.write_str("Meta")?;
40 }
41 if self.contains(Modifiers::SHIFT) {
42 if !first {
43 f.write_str(" + ")?;
44 }
45 f.write_str("Shift")?;
46 }
47 Ok(())
48 }
49}
50
51impl FromStr for Modifiers {
52 type Err = ();
53
54 fn from_str(s: &str) -> Result<Self, Self::Err> {
55 let mut modifiers = Modifiers::empty();
56 for modifier in s.split('+').map(str::trim) {
57 match modifier {
58 "Ctrl" => modifiers.insert(Modifiers::CONTROL),
59 "Alt" => modifiers.insert(Modifiers::ALT),
60 "Meta" => modifiers.insert(Modifiers::META),
61 "Shift" => modifiers.insert(Modifiers::SHIFT),
62 _ => return Err(()),
63 }
64 }
65 Ok(modifiers)
66 }
67}
68
69impl Serialize for Modifiers {
70 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71 where
72 S: serde::Serializer,
73 {
74 serializer.collect_str(self)
75 }
76}
77
78impl<'de> Deserialize<'de> for Modifiers {
79 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
80 where
81 D: serde::Deserializer<'de>,
82 {
83 deserializer.deserialize_str(ModifiersVisitor)
84 }
85}
86
87struct ModifiersVisitor;
88
89impl serde::de::Visitor<'_> for ModifiersVisitor {
90 type Value = Modifiers;
91
92 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
93 formatter.write_str("valid modifiers")
94 }
95
96 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
97 where
98 E: serde::de::Error,
99 {
100 Modifiers::from_str(v).map_err(|()| serde::de::Error::custom("invalid modifiers"))
101 }
102}