1use std::marker::PhantomData;
7
8use crate::{
9 PCWSTR, WString,
10 iter::{FabricIter, FabricListAccessor},
11};
12use mssf_com::FabricCommon::{
13 IFabricStringListResult, IFabricStringResult, IFabricStringResult_Impl,
14};
15use windows_core::implement;
16
17#[derive(Debug)]
20#[implement(IFabricStringResult)]
21pub struct StringResult {
22 data: WString,
23}
24
25impl StringResult {
28 pub fn new(data: WString) -> StringResult {
29 StringResult { data }
30 }
31}
32
33impl IFabricStringResult_Impl for StringResult_Impl {
34 fn get_String(&self) -> crate::PCWSTR {
35 crate::PCWSTR::from_raw(self.data.as_ptr())
37 }
38}
39
40fn safe_pwstr_to_wstring(raw: PCWSTR) -> WString {
44 WString::from(&raw)
45}
46
47pub struct WStringWrap {
50 h: WString,
51}
52
53impl WStringWrap {
54 pub fn into_wstring(self) -> WString {
55 self.h
56 }
57}
58
59impl From<WString> for WStringWrap {
60 fn from(value: WString) -> Self {
61 Self { h: value }
62 }
63}
64
65impl From<PCWSTR> for WStringWrap {
66 fn from(value: PCWSTR) -> Self {
67 let h = safe_pwstr_to_wstring(value);
68 Self { h }
69 }
70}
71
72impl From<WStringWrap> for WString {
73 fn from(val: WStringWrap) -> Self {
74 val.h
75 }
76}
77
78impl From<&IFabricStringResult> for WStringWrap {
79 fn from(value: &IFabricStringResult) -> Self {
80 let content = unsafe { value.get_String() };
81 let h = safe_pwstr_to_wstring(content);
82 Self { h }
83 }
84}
85
86impl From<WStringWrap> for IFabricStringResult {
87 fn from(value: WStringWrap) -> Self {
88 StringResult::new(value.h).into()
89 }
90}
91
92pub fn get_pcwstr_from_opt(opt: &Option<WString>) -> PCWSTR {
94 match opt {
95 Some(x) => PCWSTR(x.as_ptr()),
96 None => PCWSTR::null(),
97 }
98}
99
100pub struct WStringList {
103 data: Vec<WString>,
104}
105
106impl WStringList {
107 pub fn into_vec(self) -> Vec<WString> {
108 self.data
109 }
110}
111
112impl From<&IFabricStringListResult> for WStringList {
113 fn from(value: &IFabricStringListResult) -> Self {
114 let mut itemcount = 0_u32;
116 let first_str = unsafe {
117 value
118 .GetStrings(std::ptr::addr_of_mut!(itemcount))
119 .expect("cannot get strings")
120 };
121 let l = FabricStringListAccessor {
122 itemcount,
123 first_str,
124 phantom: PhantomData,
125 };
126 let itr = FabricStringListAccessorIter::new(&l, &l);
127 let data = itr.collect::<Vec<_>>();
128 Self { data }
129 }
130}
131
132pub(crate) struct FabricStringListAccessor<'a> {
133 pub(crate) itemcount: u32,
134 pub(crate) first_str: *mut PCWSTR,
135 pub(crate) phantom: PhantomData<&'a IFabricStringListResult>,
136}
137
138impl FabricListAccessor<PCWSTR> for FabricStringListAccessor<'_> {
139 fn get_count(&self) -> u32 {
140 self.itemcount
141 }
142
143 fn get_first_item(&self) -> *const PCWSTR {
144 self.first_str
145 }
146}
147
148pub(crate) type FabricStringListAccessorIter<'a> =
149 FabricIter<'a, PCWSTR, WString, FabricStringListAccessor<'a>>;
150
151#[cfg(test)]
152mod test {
153 use crate::strings::WStringWrap;
154
155 use super::StringResult;
156 use crate::WString;
157 use mssf_com::FabricCommon::IFabricStringResult;
158
159 #[test]
160 fn test_str_addr() {
161 let addr = "1.2.3.4:1234";
163
164 let haddr = WString::from(addr);
166 let haddr_slice = haddr.as_wide();
167 assert_eq!(haddr_slice.len(), 12);
168
169 let com_addr: IFabricStringResult = StringResult::new(haddr.clone()).into();
171 let raw = unsafe { com_addr.get_String() };
172 let slice = unsafe { raw.as_wide() };
173 assert_eq!(slice.len(), 12);
174
175 let haddr2: WString = WStringWrap::from(&com_addr).into();
177 assert_eq!(haddr, haddr2);
178 }
179}