|
1 | 1 | #[cfg(windows)] |
2 | 2 | use std::ffi::OsString; |
3 | | -#[cfg(unix)] |
4 | | -use std::sync::Arc; |
5 | 3 | use std::{ |
6 | 4 | borrow::Cow, |
7 | 5 | ffi::OsStr, |
8 | 6 | fmt::Debug, |
9 | 7 | path::{Path, StripPrefixError}, |
| 8 | + sync::Arc, |
10 | 9 | }; |
11 | 10 |
|
12 | 11 | use allocator_api2::alloc::Allocator; |
13 | | -#[cfg(unix)] |
14 | | -use bincode::Decode; |
15 | | -use bincode::{BorrowDecode, Encode}; |
| 12 | +use bincode::{BorrowDecode, Decode, Encode}; |
16 | 13 | use bstr::BStr; |
17 | 14 |
|
18 | 15 | /// Similar to `OsStr`, but requires zero-copy to construct from either asni or wide characters on Windows. |
@@ -161,60 +158,67 @@ impl<'a> Debug for NativeStr<'a> { |
161 | 158 |
|
162 | 159 | /// Similiar to `OsString`, but can be losslessly encoded/decoded using bincode. |
163 | 160 | /// `Encode`/`Decoded` implementations for `OsString` requires it to be valid UTF-8. This does not. |
164 | | -#[cfg(unix)] |
165 | 161 | #[derive(Encode, Decode, Clone, Hash)] |
166 | 162 | pub struct NativeString { |
| 163 | + #[cfg(unix)] |
167 | 164 | data: Arc<[u8]>, |
| 165 | + #[cfg(windows)] |
| 166 | + data: Arc<[u16]>, |
168 | 167 | } |
169 | 168 |
|
170 | 169 | impl NativeString { |
| 170 | + #[cfg(unix)] |
171 | 171 | pub fn as_os_str(&self) -> &OsStr { |
172 | 172 | use std::os::unix::ffi::OsStrExt as _; |
173 | 173 | OsStr::from_bytes(&self.data) |
174 | 174 | } |
175 | 175 |
|
| 176 | + #[cfg(windows)] |
| 177 | + pub fn to_os_string(&self) -> OsString { |
| 178 | + use std::os::windows::ffi::OsStringExt as _; |
| 179 | + OsString::from_wide(&self.data) |
| 180 | + } |
| 181 | + |
176 | 182 | pub fn to_cow_os_str(&self) -> Cow<'_, OsStr> { |
177 | 183 | #[cfg(unix)] |
178 | 184 | return Cow::Borrowed(self.as_os_str()); |
| 185 | + #[cfg(windows)] |
| 186 | + return Cow::Owned(self.to_os_string()); |
179 | 187 | } |
180 | 188 | } |
181 | 189 |
|
182 | | -#[cfg(unix)] |
183 | 190 | impl<'a> Debug for NativeString { |
184 | 191 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
185 | | - <OsStr as Debug>::fmt(self.as_os_str(), f) |
| 192 | + <OsStr as Debug>::fmt(&self.to_cow_os_str(), f) |
186 | 193 | } |
187 | 194 | } |
188 | 195 |
|
189 | | -#[cfg(unix)] |
190 | 196 | impl<'a> From<&'a OsStr> for NativeString { |
| 197 | + #[cfg(unix)] |
191 | 198 | fn from(value: &'a OsStr) -> Self { |
192 | | - use std::os::unix::ffi::OsStrExt; |
| 199 | + use std::os::unix::ffi::OsStrExt as _; |
193 | 200 | Self { data: value.as_bytes().into() } |
194 | 201 | } |
195 | | -} |
196 | | -#[cfg(unix)] |
197 | | -impl<'a> From<String> for NativeString { |
198 | | - fn from(value: String) -> Self { |
199 | | - Self { data: value.as_bytes().into() } |
| 202 | + |
| 203 | + #[cfg(windows)] |
| 204 | + fn from(value: &'a OsStr) -> Self { |
| 205 | + use std::os::windows::ffi::OsStrExt as _; |
| 206 | + Self { data: value.encode_wide().collect() } |
200 | 207 | } |
201 | 208 | } |
202 | | -#[cfg(unix)] |
| 209 | +// #[cfg(unix)] |
| 210 | +// impl<'a> From<String> for NativeString { |
| 211 | +// fn from(value: String) -> Self { |
| 212 | +// Self { data: value.as_bytes().into() } |
| 213 | +// } |
| 214 | +// } |
| 215 | + |
203 | 216 | impl<'a> From<&'a std::path::Path> for NativeString { |
204 | 217 | fn from(value: &'a std::path::Path) -> Self { |
205 | 218 | value.as_os_str().into() |
206 | 219 | } |
207 | 220 | } |
208 | 221 |
|
209 | | -#[cfg(unix)] |
210 | | -impl std::ops::Deref for NativeString { |
211 | | - type Target = OsStr; |
212 | | - |
213 | | - fn deref(&self) -> &Self::Target { |
214 | | - self.as_os_str() |
215 | | - } |
216 | | -} |
217 | | - |
218 | 222 | #[cfg(test)] |
219 | 223 | mod tests { |
220 | 224 | #[cfg(windows)] |
|
0 commit comments