lnk 0.6.4

A Rust library to parse and write Windows shortcut files (.lnk)
Documentation
use binrw::{binrw, BinRead, BinResult, BinWrite, Endian};
use bitflags::bitflags;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use std::io::{Read, Seek};

#[cfg(feature = "serde")]
use serde::Serialize;

use crate::binread_flags::binread_flags;

/// The HotkeyFlags structure specifies input generated by a combination of keyboard keys being
/// pressed.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
#[binrw]
#[cfg_attr(feature = "serde", derive(Serialize))]
pub struct HotkeyFlags {
    low_byte: HotkeyKey,
    high_byte: HotkeyModifiers,
}

impl HotkeyFlags {
    /// Create a new HotkeyFlags instance.
    pub fn new(low_byte: HotkeyKey, high_byte: HotkeyModifiers) -> Self {
        Self {
            low_byte,
            high_byte,
        }
    }

    /// The primary key assigned to the hotkey
    pub fn key(&self) -> &HotkeyKey {
        &self.low_byte
    }

    /// Set the hotkey primary key
    pub fn set_key(&mut self, key: HotkeyKey) {
        self.low_byte = key;
    }

    /// The modifiers (Shift, Ctrl, Alt) for this hotkey
    pub fn modifiers(&self) -> &HotkeyModifiers {
        &self.high_byte
    }

    /// Set the hotkey modifiers (Shift, Ctrl, Alt)
    pub fn set_modifiers(&mut self, modifiers: HotkeyModifiers) {
        self.high_byte = modifiers;
    }
}

#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, FromPrimitive, BinWrite)]
#[cfg_attr(feature = "serde", derive(Serialize))]
/// An 8-bit unsigned integer that specifies a virtual key code that corresponds to a key on the
/// keyboard.
#[bw(repr = u8)]
pub enum HotkeyKey {
    NoKeyAssigned = 0x00,
    Key0 = 0x30,
    Key1,
    Key2,
    Key3,
    Key4,
    Key5,
    Key6,
    Key7,
    Key8,
    Key9,
    KeyA = 0x41,
    KeyB,
    KeyC,
    KeyD,
    KeyE,
    KeyF,
    KeyG,
    KeyH,
    KeyI,
    KeyJ,
    KeyK,
    KeyL,
    KeyM,
    KeyN,
    KeyO,
    KeyP,
    KeyQ,
    KeyR,
    KeyS,
    KeyT,
    KeyU,
    KeyV,
    KeyW,
    KeyX,
    KeyY,
    KeyZ,
    F1 = 0x70,
    F2,
    F3,
    F4,
    F5,
    F6,
    F7,
    F8,
    F9,
    F10,
    F11,
    F12,
    F13,
    F14,
    F15,
    F16,
    F17,
    F18,
    F19,
    F20,
    F21,
    F22,
    F23,
    F24,
    NumLock = 0x90,
    ScrollLock,
}

// Custom BinRead implementation to catch invalid hotkey key from bad generated shortcuts
impl BinRead for HotkeyKey {
    type Args<'a> = ();

    fn read_options<R: Read + Seek>(
        reader: &mut R,
        options: Endian,
        _: Self::Args<'_>,
    ) -> BinResult<Self> {
        let value = u8::read_options(reader, options, ())?;
        Ok(HotkeyKey::from_u8(value).unwrap_or(HotkeyKey::NoKeyAssigned))
    }
}

bitflags! {
    /// An 8-bit unsigned integer that specifies bits that correspond to modifier keys on the
    /// keyboard
    ///
    #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
    #[cfg_attr(feature = "serde", derive(Serialize))]
    pub struct HotkeyModifiers: u8 {
        /// No modifier key is being used.
        const NO_MODIFIER       = 0x00;
        /// The "SHIFT" key on the keyboard.
        const HOTKEYF_SHIFT     = 0x01;
        /// The "CTRL" key on the keyboard.
        const HOTKEYF_CONTROL   = 0x02;
        /// The "ALT" key on the keyboard.
        const HOTKEYF_ALT       = 0x04;
    }
}

binread_flags!(HotkeyModifiers, u8);