use mssf_com::FabricCommon::{IFabricStringResult, IFabricStringResult_Impl};
use windows_core::{implement, HSTRING, PCWSTR};
#[derive(Debug)]
#[implement(IFabricStringResult)]
pub struct StringResult {
data: HSTRING,
}
impl StringResult {
pub fn new(data: HSTRING) -> StringResult {
StringResult { data }
}
}
impl IFabricStringResult_Impl for StringResult {
fn get_String(&self) -> windows::core::PCWSTR {
windows::core::PCWSTR::from_raw(self.data.as_ptr())
}
}
fn safe_pwstr_to_hstring(raw: PCWSTR) -> HSTRING {
if raw.is_null() {
return HSTRING::new();
}
HSTRING::from_wide(unsafe { raw.as_wide() }).unwrap()
}
pub struct HSTRINGWrap {
h: HSTRING,
}
impl From<HSTRING> for HSTRINGWrap {
fn from(value: HSTRING) -> Self {
Self { h: value }
}
}
impl From<PCWSTR> for HSTRINGWrap {
fn from(value: PCWSTR) -> Self {
let h = safe_pwstr_to_hstring(value);
Self { h }
}
}
impl From<HSTRINGWrap> for HSTRING {
fn from(val: HSTRINGWrap) -> Self {
val.h
}
}
impl From<&IFabricStringResult> for HSTRINGWrap {
fn from(value: &IFabricStringResult) -> Self {
let content = unsafe { value.get_String() };
let h = safe_pwstr_to_hstring(content);
Self { h }
}
}
impl From<HSTRINGWrap> for IFabricStringResult {
fn from(value: HSTRINGWrap) -> Self {
StringResult::new(value.h).into()
}
}
pub fn get_pcwstr_from_opt(opt: &Option<HSTRING>) -> PCWSTR {
match opt {
Some(x) => PCWSTR(x.as_ptr()),
None => PCWSTR::null(),
}
}
#[cfg(test)]
mod test {
use crate::strings::HSTRINGWrap;
use super::StringResult;
use mssf_com::FabricCommon::IFabricStringResult;
use windows_core::HSTRING;
#[test]
fn test_str_addr() {
let addr = "1.2.3.4:1234";
let haddr = HSTRING::from(addr);
let haddr_slice = haddr.as_wide();
assert_eq!(haddr_slice.len(), 12);
let com_addr: IFabricStringResult = StringResult::new(haddr.clone()).into();
let raw = unsafe { com_addr.get_String() };
let slice = unsafe { raw.as_wide() };
assert_eq!(slice.len(), 12);
let haddr2: HSTRING = HSTRINGWrap::from(&com_addr).into();
assert_eq!(haddr, haddr2);
}
}