1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
use std::convert::TryFrom;
use widestring::U16CString;
use winapi::{
shared::{
minwindef::UINT,
wtypes::{VT_BSTR, VT_INT, VT_UINT},
},
um::{
oaidl::VARIANT,
oleauto::{SysAllocStringLen, VariantInit},
},
};
use crate::VariantArgError;
#[derive(Debug)]
pub enum VariantArg {
Bstr(Vec<u16>),
Int(i32),
UInt(u32),
}
impl TryFrom<&str> for VariantArg {
type Error = VariantArgError;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let bstr = U16CString::from_str(value)?;
Ok(VariantArg::Bstr(bstr.into_vec()))
}
}
impl TryFrom<&String> for VariantArg {
type Error = VariantArgError;
fn try_from(value: &String) -> Result<Self, Self::Error> {
VariantArg::try_from(value.as_str())
}
}
impl From<i32> for VariantArg {
fn from(val: i32) -> Self {
VariantArg::Int(val)
}
}
impl From<u32> for VariantArg {
fn from(val: u32) -> Self {
VariantArg::UInt(val)
}
}
impl Into<VARIANT> for VariantArg {
fn into(self) -> VARIANT {
let mut v = VARIANT::default();
unsafe {
VariantInit(&mut v);
}
match &self {
VariantArg::Bstr(bstr) => unsafe {
let bstr_ptr = SysAllocStringLen(bstr.as_ptr(), bstr.len() as UINT);
let n2 = v.n1.n2_mut();
n2.vt = VT_BSTR as u16;
let _val = n2.n3.bstrVal_mut();
*_val = bstr_ptr;
println!("assigning BSTR: {:?}", _val);
},
VariantArg::Int(value) => unsafe {
let n2 = v.n1.n2_mut();
n2.vt = VT_INT as u16;
let _val = n2.n3.intVal_mut();
*_val = *value;
},
VariantArg::UInt(value) => unsafe {
let n2 = v.n1.n2_mut();
n2.vt = VT_UINT as u16;
let _val = n2.n3.uintVal_mut();
*_val = *value;
},
}
v
}
}
#[test]
fn it_converts_str_to_bstr_arg() {
let src = "Test Value";
let _arg = VariantArg::try_from(src).unwrap();
if let VariantArg::Bstr(_arg) = _arg {
let bstr = U16CString::from_str(src).unwrap().into_vec();
if !bstr.eq(&_arg) {
panic!("value in argument does not generate a valid wide char array");
}
} else {
panic!(format!("expected argument to be BSTR, got: {:?}", _arg));
}
}
#[test]
fn it_converts_string_to_bstr_arg() {
let src = String::from("Test Value");
let _arg = VariantArg::try_from(&src).unwrap();
if let VariantArg::Bstr(_arg) = _arg {
let bstr = U16CString::from_str(src.as_str()).unwrap().into_vec();
if !bstr.eq(&_arg) {
panic!("value in argument does not generate a valid wide char array");
}
} else {
panic!(format!("expected argument to be BSTR, got: {:?}", _arg));
}
}
#[test]
fn it_converts_i32_to_int_arg() {
let src: i32 = 1234;
let _arg = VariantArg::from(src);
if let VariantArg::Int(_arg) = _arg {
if _arg != src {
panic!(format!("expected {:}, got {:}", src, _arg));
}
} else {
panic!(format!("expected argument to be Int, got {:?}", _arg));
}
}
#[test]
fn it_converts_u32_to_int_arg() {
let src: u32 = 1234;
let _arg = VariantArg::from(src);
if let VariantArg::UInt(_arg) = _arg {
if _arg != src {
panic!(format!("expected {:}, got {:}", src, _arg));
}
} else {
panic!(format!("expected argument to be Uint, got {:?}", _arg));
}
}