mssf_core/
strings.rs

1// ------------------------------------------------------------
2// Copyright (c) Microsoft Corporation.  All rights reserved.
3// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4// ------------------------------------------------------------
5
6use crate::WString;
7use mssf_com::FabricCommon::{
8    IFabricStringListResult, IFabricStringResult, IFabricStringResult_Impl,
9};
10use windows_core::implement;
11
12// Basic implementation of fabric string result
13// usually used as string return value to fabric runtime.
14#[derive(Debug)]
15#[implement(IFabricStringResult)]
16pub struct StringResult {
17    data: WString,
18}
19
20// Recommend to use WStringWrap to construct this and convert to
21// IFabricStringResult.
22impl StringResult {
23    pub fn new(data: WString) -> StringResult {
24        StringResult { data }
25    }
26
27    /// Get the inner WString
28    pub fn into_inner(self) -> WString {
29        self.data
30    }
31}
32
33impl IFabricStringResult_Impl for StringResult_Impl {
34    fn get_String(&self) -> crate::PCWSTR {
35        // This is some hack to get the raw pointer out.
36        crate::PCWSTR::from_raw(self.data.as_ptr())
37    }
38}
39
40impl From<&IFabricStringResult> for StringResult {
41    fn from(value: &IFabricStringResult) -> Self {
42        let content = unsafe { value.get_String() };
43        Self {
44            data: WString::from(content),
45        }
46    }
47}
48
49// IFabricStringListResult
50pub struct WStringList {
51    data: Vec<WString>,
52}
53
54impl WStringList {
55    pub fn into_vec(self) -> Vec<WString> {
56        self.data
57    }
58}
59
60impl From<&IFabricStringListResult> for WStringList {
61    fn from(value: &IFabricStringListResult) -> Self {
62        // cpp code should not error if the parameters are not null.
63        let mut itemcount = 0_u32;
64        let first_str = unsafe {
65            value
66                .GetStrings(std::ptr::addr_of_mut!(itemcount))
67                .expect("cannot get strings")
68        };
69        let data = crate::iter::vec_from_raw_com(itemcount as usize, first_str);
70        Self { data }
71    }
72}
73
74#[cfg(test)]
75mod test {
76
77    use super::StringResult;
78    use crate::WString;
79    use mssf_com::FabricCommon::IFabricStringResult;
80
81    #[test]
82    fn test_str_addr() {
83        // Test the addr returned to SF is right.
84        let addr = "1.2.3.4:1234";
85
86        // Check wstring len.
87        let haddr = WString::from(addr);
88        let haddr_slice = haddr.as_wide();
89        assert_eq!(haddr_slice.len(), 12);
90
91        // check StringResult len.
92        let com_addr: IFabricStringResult = StringResult::new(haddr.clone()).into();
93        let raw = unsafe { com_addr.get_String() };
94        let slice = unsafe { raw.as_wide() };
95        assert_eq!(slice.len(), 12);
96
97        // check StringResult conversion is right
98        let haddr2: WString = StringResult::from(&com_addr).into_inner();
99        assert_eq!(haddr, haddr2);
100    }
101}