From b6d1c210fd2d1aa1ab55d5608727174e462b8827 Mon Sep 17 00:00:00 2001 From: Kai <7957852+kaivol@users.noreply.github.com> Date: Thu, 14 Apr 2022 01:05:19 +0200 Subject: [PATCH 1/4] Added conversion to/from OsStr/OsString to HSTRING --- crates/libs/windows/src/core/hstring.rs | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/crates/libs/windows/src/core/hstring.rs b/crates/libs/windows/src/core/hstring.rs index 810b184b69..2bfbff176d 100644 --- a/crates/libs/windows/src/core/hstring.rs +++ b/crates/libs/windows/src/core/hstring.rs @@ -48,6 +48,11 @@ impl HSTRING { alloc::string::String::from_utf16_lossy(self.as_wide()) } + /// Get the contents of this `HSTRING` as a OsString. + pub fn to_os_string(&self) -> std::ffi::OsString { + std::os::windows::ffi::OsStringExt::from_wide(self.as_wide()) + } + /// Clear the contents of the string and free the memory if `self` holds the /// last reference to the string data. pub fn clear(&mut self) { @@ -164,6 +169,24 @@ impl core::convert::From<&alloc::string::String> for HSTRING { } } +impl core::convert::From<&std::ffi::OsStr> for HSTRING { + fn from(value: &std::ffi::OsStr) -> Self { + unsafe { Self::from_wide_iter(std::os::windows::ffi::OsStrExt::encode_wide(value), value.len() as u32) } + } +} + +impl core::convert::From for HSTRING { + fn from(value: std::ffi::OsString) -> Self { + value.as_os_str().into() + } +} + +impl core::convert::From<&std::ffi::OsString> for HSTRING { + fn from(value: &std::ffi::OsString) -> Self { + value.as_os_str().into() + } +} + impl PartialEq for HSTRING { fn eq(&self, other: &Self) -> bool { *self.as_wide() == *other.as_wide() @@ -258,6 +281,18 @@ impl core::convert::TryFrom for alloc::string::String { } } +impl<'a> core::convert::From<&'a HSTRING> for std::ffi::OsString { + fn from(hstring: &HSTRING) -> Self { + std::os::windows::ffi::OsStringExt::from_wide(hstring.as_wide()) + } +} + +impl core::convert::From for std::ffi::OsString { + fn from(hstring: HSTRING) -> Self { + Self::from(&hstring) + } +} + #[cfg(feature = "alloc")] impl<'a> IntoParam<'a, HSTRING> for &str { fn into_param(self) -> Param<'a, HSTRING> { @@ -272,6 +307,18 @@ impl<'a> IntoParam<'a, HSTRING> for alloc::string::String { } } +impl<'a> IntoParam<'a, HSTRING> for &std::ffi::OsStr { + fn into_param(self) -> Param<'a, HSTRING> { + Param::Owned(self.into()) + } +} + +impl<'a> IntoParam<'a, HSTRING> for std::ffi::OsString { + fn into_param(self) -> Param<'a, HSTRING> { + Param::Owned(self.into()) + } +} + const REFERENCE_FLAG: u32 = 1; #[repr(C)] From fb31b3afc1e8e43791a9597d2c5833566e50b1fc Mon Sep 17 00:00:00 2001 From: Kai <7957852+kaivol@users.noreply.github.com> Date: Thu, 14 Apr 2022 13:15:29 +0200 Subject: [PATCH 2/4] Added PartialEq for OsStr/OsString --- crates/libs/windows/src/core/hstring.rs | 74 ++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/crates/libs/windows/src/core/hstring.rs b/crates/libs/windows/src/core/hstring.rs index 2bfbff176d..f8166b0490 100644 --- a/crates/libs/windows/src/core/hstring.rs +++ b/crates/libs/windows/src/core/hstring.rs @@ -265,6 +265,78 @@ impl PartialEq<&HSTRING> for alloc::string::String { } } +impl PartialEq for HSTRING { + fn eq(&self, other: &std::ffi::OsString) -> bool { + *self == **other + } +} + +impl PartialEq for &HSTRING { + fn eq(&self, other: &std::ffi::OsString) -> bool { + **self == **other + } +} + +impl PartialEq<&std::ffi::OsString> for HSTRING { + fn eq(&self, other: &&std::ffi::OsString) -> bool { + *self == ***other + } +} + +impl PartialEq for HSTRING { + fn eq(&self, other: &std::ffi::OsStr) -> bool { + self.as_wide().iter().copied().eq(std::os::windows::ffi::OsStrExt::encode_wide(other)) + } +} + +impl PartialEq for &HSTRING { + fn eq(&self, other: &std::ffi::OsStr) -> bool { + **self == *other + } +} + +impl PartialEq<&std::ffi::OsStr> for HSTRING { + fn eq(&self, other: &&std::ffi::OsStr) -> bool { + *self == **other + } +} + +impl PartialEq for std::ffi::OsStr { + fn eq(&self, other: &HSTRING) -> bool { + *other == *self + } +} + +impl PartialEq for &std::ffi::OsStr { + fn eq(&self, other: &HSTRING) -> bool { + *other == **self + } +} + +impl PartialEq<&HSTRING> for std::ffi::OsStr { + fn eq(&self, other: &&HSTRING) -> bool { + **other == *self + } +} + +impl PartialEq for std::ffi::OsString { + fn eq(&self, other: &HSTRING) -> bool { + *other == **self + } +} + +impl PartialEq for &std::ffi::OsString { + fn eq(&self, other: &HSTRING) -> bool { + *other == ***self + } +} + +impl PartialEq<&HSTRING> for std::ffi::OsString { + fn eq(&self, other: &&HSTRING) -> bool { + **other == **self + } +} + impl<'a> core::convert::TryFrom<&'a HSTRING> for alloc::string::String { type Error = alloc::string::FromUtf16Error; @@ -283,7 +355,7 @@ impl core::convert::TryFrom for alloc::string::String { impl<'a> core::convert::From<&'a HSTRING> for std::ffi::OsString { fn from(hstring: &HSTRING) -> Self { - std::os::windows::ffi::OsStringExt::from_wide(hstring.as_wide()) + hstring.to_os_string() } } From efcda0371c0c983fbeec0f19140b94fdd5ae487b Mon Sep 17 00:00:00 2001 From: Kai <7957852+kaivol@users.noreply.github.com> Date: Thu, 14 Apr 2022 13:15:43 +0200 Subject: [PATCH 3/4] Added tests --- crates/tests/core/tests/hstrings.rs | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/crates/tests/core/tests/hstrings.rs b/crates/tests/core/tests/hstrings.rs index 7fab2806a4..0f4109bf01 100644 --- a/crates/tests/core/tests/hstrings.rs +++ b/crates/tests/core/tests/hstrings.rs @@ -53,6 +53,16 @@ fn from_empty_string() { assert!(format!("{}", h).is_empty()); } +#[test] +fn from_os_string_string() { + let wide_data = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063]; + use std::os::windows::prelude::OsStringExt; + let o = std::ffi::OsString::from_wide(wide_data); + let h = StringType::from(o); + let d = StringType::from_wide(wide_data); + assert_eq!(h, d); +} + #[test] fn hstring_to_string() { let h = StringType::from("test"); @@ -78,6 +88,16 @@ fn hstring_to_string_lossy() { assert_eq!(s, "𝄞mu�ic"); } +#[test] +fn hstring_to_os_string() { + // 𝄞muic + let wide_data = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063]; + let h = StringType::from_wide(wide_data); + let s = h.to_os_string(); + use std::os::windows::prelude::OsStringExt; + assert_eq!(s, std::ffi::OsString::from_wide(wide_data)); +} + #[test] fn hstring_equality_combinations() { let h = StringType::from("test"); @@ -104,3 +124,32 @@ fn hstring_equality_combinations() { assert_eq!(ss, h); assert_eq!(ss, &h); } + +#[test] +fn hstring_osstring_equality_combinations() { + let wide_data = &[0xD834, 0xDD1E, 0x006d, 0x0075, 0xD800, 0x0069, 0x0063]; + let h = StringType::from_wide(wide_data); + use std::os::windows::prelude::OsStringExt; + let s = std::ffi::OsString::from_wide(wide_data); + let ss = s.as_os_str(); + + assert_eq!(h, s); + assert_eq!(&h, s); + assert_eq!(h, &s); + assert_eq!(&h, &s); + + assert_eq!(s, h); + assert_eq!(s, &h); + assert_eq!(&s, h); + assert_eq!(&s, &h); + + assert_eq!(h, *ss); + assert_eq!(&h, *ss); + assert_eq!(h, ss); + assert_eq!(&h, ss); + + assert_eq!(*ss, h); + assert_eq!(*ss, &h); + assert_eq!(ss, h); + assert_eq!(ss, &h); +} From 1e2cd8ccd9a72a62127621937e1ae1f253090416 Mon Sep 17 00:00:00 2001 From: Kai <7957852+kaivol@users.noreply.github.com> Date: Thu, 14 Apr 2022 15:01:45 +0200 Subject: [PATCH 4/4] added alloc feature gates --- crates/libs/windows/src/core/hstring.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crates/libs/windows/src/core/hstring.rs b/crates/libs/windows/src/core/hstring.rs index f8166b0490..10b96d7779 100644 --- a/crates/libs/windows/src/core/hstring.rs +++ b/crates/libs/windows/src/core/hstring.rs @@ -379,12 +379,14 @@ impl<'a> IntoParam<'a, HSTRING> for alloc::string::String { } } +#[cfg(feature = "alloc")] impl<'a> IntoParam<'a, HSTRING> for &std::ffi::OsStr { fn into_param(self) -> Param<'a, HSTRING> { Param::Owned(self.into()) } } +#[cfg(feature = "alloc")] impl<'a> IntoParam<'a, HSTRING> for std::ffi::OsString { fn into_param(self) -> Param<'a, HSTRING> { Param::Owned(self.into())