win-variant 0.1.2

This is a rust crate that aims to provide a more ergonomic way of working with variants in winapi based projects.
Documentation
use std::convert::TryFrom;

use widestring::U16CString;
use winapi::um::oaidl::VARIANT;

use super::errors::VariantResultError;

use winapi::shared::wtypes::{VT_BSTR, VT_EMPTY, VT_INT, VT_UINT};

/// VariantResult is a tyoe that can be converted from VARIANT to automatically
/// convert the VARIANT value to a rust type that is easier to work with.
/// The VARIANT can be dropped after the conversion as the data is copied
/// into the VariantResult.
#[derive(Debug)]
pub enum VariantResult {
    Empty,
    String(String),
    Int(i32),
    Uint(u32),
}

impl TryFrom<VARIANT> for VariantResult {
    type Error = VariantResultError;

    fn try_from(value: VARIANT) -> Result<Self, Self::Error> {
        unsafe {
            let n2 = value.n1.n2();
            let n3 = n2.n3;
            match n2.vt as u32 {
                VT_EMPTY => Ok(VariantResult::Empty),
                VT_BSTR => {
                    let p = n3.bstrVal().as_ref().unwrap();
                    let u16_str = U16CString::from_ptr_str(p);
                    Ok(VariantResult::String(u16_str.to_string()?))
                }
                VT_INT => {
                    let v = n3.intVal();
                    Ok(VariantResult::Int(*v))
                }
                VT_UINT => {
                    let v = n3.uintVal();
                    Ok(VariantResult::Uint(*v))
                }
                _ => Err(VariantResultError::UnsupportedTypeConversion(n2.vt)),
            }
        }
    }
}