inlyne 0.2.1

Introducing Inlyne, a GPU powered yet browsless tool to help you quickly view markdown files in the blink of an eye.
use std::str::FromStr;

use super::{Key, KeyCombo, ModifiedKey};

use serde::{de, Deserialize, Deserializer};
use winit::event::ModifiersState;

impl<'de> Deserialize<'de> for Key {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        #[serde(untagged)]
        enum StringOrNum {
            Str(String),
            Num(u32),
        }

        match StringOrNum::deserialize(deserializer)? {
            StringOrNum::Str(s) => Key::from_str(&s).map_err(de::Error::custom),
            StringOrNum::Num(num) => Ok(Self::ScanCode(num)),
        }
    }
}

impl<'de> Deserialize<'de> for ModifiedKey {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        enum ModifierType {
            Alt,
            Ctrl,
            Os,
            Shift,
        }

        #[derive(Deserialize)]
        struct Inner {
            key: Key,
            r#mod: Vec<ModifierType>,
        }

        #[derive(Deserialize)]
        #[serde(untagged)]
        enum KeyOrModifiedKey {
            Key(Key),
            ModifiedKey(Inner),
        }

        Ok(match KeyOrModifiedKey::deserialize(deserializer)? {
            KeyOrModifiedKey::Key(key) => ModifiedKey(key, ModifiersState::empty()),
            KeyOrModifiedKey::ModifiedKey(Inner { key, r#mod }) => {
                let mut modifiers = ModifiersState::empty();
                for ty in r#mod {
                    modifiers |= match ty {
                        ModifierType::Alt => ModifiersState::ALT,
                        ModifierType::Ctrl => ModifiersState::CTRL,
                        ModifierType::Os => ModifiersState::LOGO,
                        ModifierType::Shift => ModifiersState::SHIFT,
                    };
                }

                ModifiedKey(key, modifiers)
            }
        })
    }
}

impl<'de> Deserialize<'de> for KeyCombo {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        #[derive(Deserialize)]
        #[serde(untagged)]
        enum ModifiedKeyOrModifiedKeys {
            Key(ModifiedKey),
            Keys(Vec<ModifiedKey>),
        }

        let keys = match ModifiedKeyOrModifiedKeys::deserialize(deserializer)? {
            ModifiedKeyOrModifiedKeys::Key(key) => vec![key],
            ModifiedKeyOrModifiedKeys::Keys(keys) => keys,
        };

        Ok(KeyCombo(keys))
    }
}