hyprshell_config_lib/
modifier.rs1use anyhow::bail;
2use serde::de::Visitor;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::fmt;
5
6#[derive(Debug, Clone, Copy, Eq, PartialEq)]
7pub enum Modifier {
8 Alt,
9 Ctrl,
10 Super,
11 None,
12}
13
14#[allow(clippy::must_use_candidate)]
15impl Modifier {
16 pub fn to_l_key(&self) -> String {
17 self.to_keysym_l().to_string()
18 }
19 pub const fn to_keysym_l(&self) -> &'static str {
20 match self {
24 Self::Alt => "Alt_L",
25 Self::Ctrl => "Control_L",
26 Self::Super => "Super_L",
27 Self::None => "",
28 }
29 }
30 pub const fn to_keysym_r(&self) -> &'static str {
31 match self {
32 Self::Alt => "Alt_R",
33 Self::Ctrl => "Control_R",
34 Self::Super => "Super_R",
35 Self::None => "",
36 }
37 }
38 pub const fn to_str(&self) -> &'static str {
39 match self {
40 Self::Alt => "alt",
41 Self::Ctrl => "ctrl",
42 Self::Super => "super",
43 Self::None => "none",
44 }
45 }
46}
47
48impl<'de> Deserialize<'de> for Modifier {
49 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
50 where
51 D: Deserializer<'de>,
52 {
53 struct ModVisitor;
54 impl Visitor<'_> for ModVisitor {
55 type Value = Modifier;
56 fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
57 fmt.write_str("one of: alt, ctrl, super, none")
58 }
59 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
60 where
61 E: serde::de::Error,
62 {
63 value
64 .try_into()
65 .map_err(|_e| E::unknown_variant(value, &["alt", "ctrl", "super", "none"]))
66 }
67 }
68 deserializer.deserialize_str(ModVisitor)
69 }
70}
71
72impl Serialize for Modifier {
73 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
74 where
75 S: Serializer,
76 {
77 let s = self.to_str();
78 serializer.serialize_str(s)
79 }
80}
81
82impl TryFrom<&str> for Modifier {
83 type Error = anyhow::Error;
84
85 fn try_from(value: &str) -> Result<Self, Self::Error> {
86 match value.to_ascii_lowercase().as_str() {
87 "alt" => Ok(Self::Alt),
88 "ctrl" | "control" => Ok(Self::Ctrl),
89 "super" | "win" | "windows" | "meta" => Ok(Self::Super),
90 "none" | "" => Ok(Self::None),
91 other => bail!("Invalid modifier: {other}"),
92 }
93 }
94}
95
96impl fmt::Display for Modifier {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 Self::Alt => write!(f, "Alt"),
100 Self::Ctrl => write!(f, "Ctrl"),
101 Self::Super => write!(f, "Super"),
102 Self::None => write!(f, "None"),
103 }
104 }
105}