hyprshell_config_lib/
modifier.rs

1use 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}
12
13#[allow(clippy::must_use_candidate)]
14impl Modifier {
15    pub fn to_l_key(&self) -> String {
16        match self {
17            Self::Alt => "alt_l".to_string(),
18            Self::Ctrl => "ctrl_l".to_string(),
19            Self::Super => "super_l".to_string(),
20        }
21    }
22    pub const fn to_str(&self) -> &'static str {
23        match self {
24            Self::Alt => "alt",
25            Self::Ctrl => "ctrl",
26            Self::Super => "super",
27        }
28    }
29}
30
31impl<'de> Deserialize<'de> for Modifier {
32    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
33    where
34        D: Deserializer<'de>,
35    {
36        struct ModVisitor;
37        impl Visitor<'_> for ModVisitor {
38            type Value = Modifier;
39            fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
40                fmt.write_str("one of: alt, ctrl, super")
41            }
42            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
43            where
44                E: serde::de::Error,
45            {
46                value
47                    .try_into()
48                    .map_err(|_e| E::unknown_variant(value, &["alt", "ctrl", "super"]))
49            }
50        }
51        deserializer.deserialize_str(ModVisitor)
52    }
53}
54
55impl Serialize for Modifier {
56    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
57    where
58        S: Serializer,
59    {
60        let s = self.to_str();
61        serializer.serialize_str(s)
62    }
63}
64
65impl TryFrom<&str> for Modifier {
66    type Error = anyhow::Error;
67
68    fn try_from(value: &str) -> Result<Self, Self::Error> {
69        match value.to_ascii_lowercase().as_str() {
70            "Alt" | "alt" => Ok(Self::Alt),
71            "Ctrl" | "ctrl" | "control" | "Control" => Ok(Self::Ctrl),
72            "Super" | "super" | "Win" | "win" | "windows" | "Windows" => Ok(Self::Super),
73            other => bail!("Invalid modifier: {}", other),
74        }
75    }
76}
77
78impl fmt::Display for Modifier {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        match self {
81            Self::Alt => write!(f, "Alt"),
82            Self::Ctrl => write!(f, "Ctrl"),
83            Self::Super => write!(f, "Super"),
84        }
85    }
86}