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