mod arg;
mod errors;
mod result;
use winapi::{
shared::wtypes::{VARENUM, VT_BSTR},
um::{
oaidl::VARIANT,
oleauto::{SysFreeString, VariantClear},
},
};
pub use arg::VariantArg;
pub use errors::{VariantArgError, VariantResultError};
pub use result::VariantResult;
pub fn free_variants(variants: &mut Vec<VARIANT>) {
for variant in variants {
unsafe {
free_variant(variant);
}
}
}
pub unsafe fn free_variant(variant: &mut VARIANT) {
match variant.n1.n2().vt as VARENUM {
VT_BSTR => {
let p = variant.n1.n2_mut().n3.bstrVal();
println!("freeing BSTR: {:?}", p);
SysFreeString(*p);
}
_ => (),
};
VariantClear(variant);
}
#[cfg(test)]
mod tests {
use crate::{free_variant, VariantArg, VariantResult};
use std::convert::TryFrom;
use winapi::um::oaidl::VARIANT;
#[test]
fn it_converts_to_result_from_bstr_arg() {
let src = "Test Value";
let _arg = VariantArg::try_from(src).unwrap();
let mut v: VARIANT = _arg.into();
let result = VariantResult::try_from(v).unwrap();
unsafe {
free_variant(&mut v);
}
if let VariantResult::String(v) = result {
if !src.eq(&v) {
panic!(format!("expected {:?}, got {:?}", src, v));
}
} else {
panic!(format!("expected String, got: {:?}", result));
}
}
#[test]
fn it_converts_to_result_from_int_arg() {
let src: i32 = 1234;
let _arg = VariantArg::from(src);
let mut v: VARIANT = _arg.into();
let result = VariantResult::try_from(v).unwrap();
unsafe {
free_variant(&mut v);
}
if let VariantResult::Int(v) = result {
if src != v {
panic!(format!("expected {:}, got {:}", src, v));
}
} else {
panic!(format!("expected Int, got {:?}", result));
}
}
#[test]
fn it_converts_to_result_from_uint_arg() {
let src: u32 = 1234;
let _arg = VariantArg::from(src);
let mut v: VARIANT = _arg.into();
let result = VariantResult::try_from(v).unwrap();
unsafe {
free_variant(&mut v);
}
if let VariantResult::Uint(v) = result {
if src != v {
panic!(format!("expected {:}, got {:}", src, v));
}
} else {
panic!(format!("expected Int, got {:?}", result));
}
}
}