hyprshell-config-lib 4.10.0

A library for reading, writing and migrating configuration files for hyprshell
Documentation
use anyhow::bail;
use serde::de::Visitor;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Modifier {
    Alt,
    Ctrl,
    Super,
    None,
}

#[allow(clippy::must_use_candidate)]
impl Modifier {
    pub fn to_l_key(&self) -> String {
        match self {
            Self::Alt => "alt_l".to_string(),
            Self::Ctrl => "ctrl_l".to_string(),
            Self::Super => "super_l".to_string(),
            Self::None => String::new(),
        }
    }
    pub const fn to_str(&self) -> &'static str {
        match self {
            Self::Alt => "alt",
            Self::Ctrl => "ctrl",
            Self::Super => "super",
            Self::None => "none",
        }
    }
}

impl<'de> Deserialize<'de> for Modifier {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct ModVisitor;
        impl Visitor<'_> for ModVisitor {
            type Value = Modifier;
            fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                fmt.write_str("one of: alt, ctrl, super, none")
            }
            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
            where
                E: serde::de::Error,
            {
                value
                    .try_into()
                    .map_err(|_e| E::unknown_variant(value, &["alt", "ctrl", "super", "none"]))
            }
        }
        deserializer.deserialize_str(ModVisitor)
    }
}

impl Serialize for Modifier {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let s = self.to_str();
        serializer.serialize_str(s)
    }
}

impl TryFrom<&str> for Modifier {
    type Error = anyhow::Error;

    fn try_from(value: &str) -> Result<Self, Self::Error> {
        match value.to_ascii_lowercase().as_str() {
            "alt" => Ok(Self::Alt),
            "ctrl" | "control" => Ok(Self::Ctrl),
            "super" | "win" | "windows" | "meta" => Ok(Self::Super),
            "none" | "" => Ok(Self::None),
            other => bail!("Invalid modifier: {other}"),
        }
    }
}

impl fmt::Display for Modifier {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Alt => write!(f, "Alt"),
            Self::Ctrl => write!(f, "Ctrl"),
            Self::Super => write!(f, "Super"),
            Self::None => write!(f, "None"),
        }
    }
}