ncrypt 0.2.0

WIP rust bindings for the win32 ncrypt api
Documentation
use thiserror::Error;
use windows_sys::Win32::Foundation::{
    NTE_BAD_FLAGS, NTE_BAD_KEYSET, NTE_DEVICE_NOT_READY, NTE_EXISTS, NTE_INVALID_PARAMETER,
    NTE_NO_MEMORY,
};

#[derive(Debug, Error, PartialEq)]
pub enum Error {
    #[error("invalid flags specified")]
    BadFlags,
    #[error("the parameter is incorrect")]
    InvalidParameter,
    #[error("insufficient memory available for the operation")]
    NoMemory,
    #[error("keyset does not exist")]
    BadKeyset,
    #[error("the device that is required by this cryptographic provider is not ready for use")]
    DeviceNotReady,
    #[error("object already exists")]
    ObjectExists,
    #[error("unknown error occurred 0x{0:X}")]
    Other(i32),

    #[error("failed to parse (exported) key: {0}")]
    KeyParse(#[from] ParseError),
}

#[derive(Debug, Error, PartialEq)]
pub enum ParseError {
    #[error("size too small")]
    TooSmall,
    #[error("size doesn't add up, expected: 0x{expected:X} actual: 0x{actual:X}")]
    SizeMismatch { expected: usize, actual: usize },
    #[error("unexpected key type")]
    UnexpectedType,
    #[error("internal rsa error")]
    Rsa(#[from] rsa::Error),
}

impl Error {
    pub const fn from_status(status: i32) -> Result<(), Self> {
        match status {
            0 => Ok(()),
            NTE_BAD_FLAGS => Err(Self::BadFlags),
            NTE_INVALID_PARAMETER => Err(Self::InvalidParameter),
            NTE_NO_MEMORY => Err(Self::NoMemory),
            NTE_BAD_KEYSET => Err(Self::BadKeyset),
            NTE_DEVICE_NOT_READY => Err(Self::DeviceNotReady),
            NTE_EXISTS => Err(Self::ObjectExists),
            other => Err(Self::Other(other)),
        }
    }
}