/rust/registry/src/index.crates.io-1949cf8c6b5b557f/widestring-0.4.3/src/ucstring.rs
Line | Count | Source |
1 | | use crate::{MissingNulError, UCStr, UChar, UStr, UString, WideChar}; |
2 | | use core::{ |
3 | | borrow::Borrow, |
4 | | mem, |
5 | | mem::ManuallyDrop, |
6 | | ops::{Deref, Index, RangeFull}, |
7 | | ptr, slice, |
8 | | }; |
9 | | |
10 | | #[cfg(all(feature = "alloc", not(feature = "std")))] |
11 | | use alloc::{ |
12 | | borrow::{Cow, ToOwned}, |
13 | | boxed::Box, |
14 | | vec::Vec, |
15 | | }; |
16 | | #[cfg(feature = "std")] |
17 | | use std::{ |
18 | | borrow::{Cow, ToOwned}, |
19 | | boxed::Box, |
20 | | vec::Vec, |
21 | | }; |
22 | | |
23 | | /// An owned, mutable C-style "wide" string for FFI that is nul-aware and nul-terminated. |
24 | | /// |
25 | | /// `UCString` is aware of nul values. Unless unchecked conversions are used, all `UCString` |
26 | | /// strings end with a nul-terminator in the underlying buffer and contain no internal nul values. |
27 | | /// The strings may still contain invalid or ill-formed UTF-16 or UTF-32 data. These strings are |
28 | | /// intended to be used with FFI functions such as Windows API that may require nul-terminated |
29 | | /// strings. |
30 | | /// |
31 | | /// `UCString` can be converted to and from many other string types, including `UString`, |
32 | | /// `OsString`, and `String`, making proper Unicode FFI safe and easy. |
33 | | /// |
34 | | /// Please prefer using the type aliases `U16CString` or `U32CString` or `WideCString` to using |
35 | | /// this type directly. |
36 | | /// |
37 | | /// # Examples |
38 | | /// |
39 | | /// The following example constructs a `U16CString` and shows how to convert a `U16CString` to a |
40 | | /// regular Rust `String`. |
41 | | /// |
42 | | /// ```rust |
43 | | /// use widestring::U16CString; |
44 | | /// let s = "Test"; |
45 | | /// // Create a wide string from the rust string |
46 | | /// let wstr = U16CString::from_str(s).unwrap(); |
47 | | /// // Convert back to a rust string |
48 | | /// let rust_str = wstr.to_string_lossy(); |
49 | | /// assert_eq!(rust_str, "Test"); |
50 | | /// ``` |
51 | | /// |
52 | | /// The same example using `U32CString`: |
53 | | /// |
54 | | /// ```rust |
55 | | /// use widestring::U32CString; |
56 | | /// let s = "Test"; |
57 | | /// // Create a wide string from the rust string |
58 | | /// let wstr = U32CString::from_str(s).unwrap(); |
59 | | /// // Convert back to a rust string |
60 | | /// let rust_str = wstr.to_string_lossy(); |
61 | | /// assert_eq!(rust_str, "Test"); |
62 | | /// ``` |
63 | | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
64 | | pub struct UCString<C: UChar> { |
65 | | pub(crate) inner: Box<[C]>, |
66 | | } |
67 | | |
68 | | /// An error returned from `UCString` to indicate that an invalid nul value was found. |
69 | | /// |
70 | | /// The error indicates the position in the vector where the nul value was found, as well as |
71 | | /// returning the ownership of the invalid vector. |
72 | | #[derive(Debug, Clone, PartialEq, Eq)] |
73 | | pub struct NulError<C: UChar>(usize, Vec<C>); |
74 | | |
75 | | impl<C: UChar> UCString<C> { |
76 | | /// Constructs a `UCString` from a container of wide character data. |
77 | | /// |
78 | | /// This method will consume the provided data and use the underlying elements to construct a |
79 | | /// new string. The data will be scanned for invalid nul values. |
80 | | /// |
81 | | /// # Failures |
82 | | /// |
83 | | /// This function will return an error if the data contains a nul value. |
84 | | /// The returned error will contain the `Vec` as well as the position of the nul value. |
85 | | /// |
86 | | /// # Examples |
87 | | /// |
88 | | /// ```rust |
89 | | /// use widestring::U16CString; |
90 | | /// let v = vec![84u16, 104u16, 101u16]; // 'T' 'h' 'e' |
91 | | /// # let cloned = v.clone(); |
92 | | /// // Create a wide string from the vector |
93 | | /// let wcstr = U16CString::new(v).unwrap(); |
94 | | /// # assert_eq!(wcstr.into_vec(), cloned); |
95 | | /// ``` |
96 | | /// |
97 | | /// ```rust |
98 | | /// use widestring::U32CString; |
99 | | /// let v = vec![84u32, 104u32, 101u32]; // 'T' 'h' 'e' |
100 | | /// # let cloned = v.clone(); |
101 | | /// // Create a wide string from the vector |
102 | | /// let wcstr = U32CString::new(v).unwrap(); |
103 | | /// # assert_eq!(wcstr.into_vec(), cloned); |
104 | | /// ``` |
105 | | /// |
106 | | /// The following example demonstrates errors from nul values in a vector. |
107 | | /// |
108 | | /// ```rust |
109 | | /// use widestring::U16CString; |
110 | | /// let v = vec![84u16, 0u16, 104u16, 101u16]; // 'T' NUL 'h' 'e' |
111 | | /// // Create a wide string from the vector |
112 | | /// let res = U16CString::new(v); |
113 | | /// assert!(res.is_err()); |
114 | | /// assert_eq!(res.err().unwrap().nul_position(), 1); |
115 | | /// ``` |
116 | | /// |
117 | | /// ```rust |
118 | | /// use widestring::U32CString; |
119 | | /// let v = vec![84u32, 0u32, 104u32, 101u32]; // 'T' NUL 'h' 'e' |
120 | | /// // Create a wide string from the vector |
121 | | /// let res = U32CString::new(v); |
122 | | /// assert!(res.is_err()); |
123 | | /// assert_eq!(res.err().unwrap().nul_position(), 1); |
124 | | /// ``` |
125 | 58.9k | pub fn new(v: impl Into<Vec<C>>) -> Result<Self, NulError<C>> { |
126 | 58.9k | let v = v.into(); |
127 | | // Check for nul vals |
128 | 484k | match v.iter().position(|&val| val == UChar::NUL) {<widestring::ucstring::UCString<u16>>::new::<alloc::vec::Vec<u16>>::{closure#0}Line | Count | Source | 128 | 229k | match v.iter().position(|&val| val == UChar::NUL) { |
<widestring::ucstring::UCString<u16>>::new::<alloc::vec::Vec<u16>>::{closure#0}Line | Count | Source | 128 | 254k | match v.iter().position(|&val| val == UChar::NUL) { |
Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::new::<&[u32]>::{closure#0}Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::new::<&[u16]>::{closure#0} |
129 | 58.9k | None => Ok(unsafe { UCString::from_vec_unchecked(v) }), |
130 | 0 | Some(pos) => Err(NulError(pos, v)), |
131 | | } |
132 | 58.9k | } <widestring::ucstring::UCString<u16>>::new::<alloc::vec::Vec<u16>> Line | Count | Source | 125 | 29.9k | pub fn new(v: impl Into<Vec<C>>) -> Result<Self, NulError<C>> { | 126 | 29.9k | let v = v.into(); | 127 | | // Check for nul vals | 128 | 29.9k | match v.iter().position(|&val| val == UChar::NUL) { | 129 | 29.9k | None => Ok(unsafe { UCString::from_vec_unchecked(v) }), | 130 | 0 | Some(pos) => Err(NulError(pos, v)), | 131 | | } | 132 | 29.9k | } |
<widestring::ucstring::UCString<u16>>::new::<alloc::vec::Vec<u16>> Line | Count | Source | 125 | 28.9k | pub fn new(v: impl Into<Vec<C>>) -> Result<Self, NulError<C>> { | 126 | 28.9k | let v = v.into(); | 127 | | // Check for nul vals | 128 | 28.9k | match v.iter().position(|&val| val == UChar::NUL) { | 129 | 28.9k | None => Ok(unsafe { UCString::from_vec_unchecked(v) }), | 130 | 0 | Some(pos) => Err(NulError(pos, v)), | 131 | | } | 132 | 28.9k | } |
Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::new::<&[u32]> Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::new::<&[u16]> |
133 | | |
134 | | /// Constructs a `UCString` from a nul-terminated container of UTF-16 or UTF-32 data. |
135 | | /// |
136 | | /// This method will consume the provided data and use the underlying elements to construct a |
137 | | /// new string. The string will be truncated at the first nul value in the string. |
138 | | /// |
139 | | /// # Failures |
140 | | /// |
141 | | /// This function will return an error if the data does not contain a nul to terminate the |
142 | | /// string. The returned error will contain the consumed `Vec`. |
143 | | /// |
144 | | /// # Examples |
145 | | /// |
146 | | /// ```rust |
147 | | /// use widestring::U16CString; |
148 | | /// let v = vec![84u16, 104u16, 101u16, 0u16]; // 'T' 'h' 'e' NUL |
149 | | /// # let cloned = v[..3].to_owned(); |
150 | | /// // Create a wide string from the vector |
151 | | /// let wcstr = U16CString::from_vec_with_nul(v).unwrap(); |
152 | | /// # assert_eq!(wcstr.into_vec(), cloned); |
153 | | /// ``` |
154 | | /// |
155 | | /// ```rust |
156 | | /// use widestring::U32CString; |
157 | | /// let v = vec![84u32, 104u32, 101u32, 0u32]; // 'T' 'h' 'e' NUL |
158 | | /// # let cloned = v[..3].to_owned(); |
159 | | /// // Create a wide string from the vector |
160 | | /// let wcstr = U32CString::from_vec_with_nul(v).unwrap(); |
161 | | /// # assert_eq!(wcstr.into_vec(), cloned); |
162 | | /// ``` |
163 | | /// |
164 | | /// The following example demonstrates errors from missing nul values in a vector. |
165 | | /// |
166 | | /// ```rust |
167 | | /// use widestring::U16CString; |
168 | | /// let v = vec![84u16, 104u16, 101u16]; // 'T' 'h' 'e' |
169 | | /// // Create a wide string from the vector |
170 | | /// let res = U16CString::from_vec_with_nul(v); |
171 | | /// assert!(res.is_err()); |
172 | | /// ``` |
173 | | /// |
174 | | /// ```rust |
175 | | /// use widestring::U32CString; |
176 | | /// let v = vec![84u32, 104u32, 101u32]; // 'T' 'h' 'e' |
177 | | /// // Create a wide string from the vector |
178 | | /// let res = U32CString::from_vec_with_nul(v); |
179 | | /// assert!(res.is_err()); |
180 | | /// ``` |
181 | 0 | pub fn from_vec_with_nul(v: impl Into<Vec<C>>) -> Result<Self, MissingNulError<C>> { |
182 | 0 | let mut v = v.into(); |
183 | | // Check for nul vals |
184 | 0 | match v.iter().position(|&val| val == UChar::NUL) {Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::from_vec_with_nul::<&[u32]>::{closure#0}Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::from_vec_with_nul::<&[u16]>::{closure#0} |
185 | 0 | None => Err(MissingNulError { inner: Some(v) }), |
186 | 0 | Some(pos) => { |
187 | 0 | v.truncate(pos + 1); |
188 | 0 | Ok(unsafe { UCString::from_vec_with_nul_unchecked(v) }) |
189 | | } |
190 | | } |
191 | 0 | } Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::from_vec_with_nul::<&[u32]> Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::from_vec_with_nul::<&[u16]> |
192 | | |
193 | | /// Creates a `UCString` from a vector without checking for interior nul values. |
194 | | /// |
195 | | /// A terminating nul value will be appended if the vector does not already have a terminating |
196 | | /// nul. |
197 | | /// |
198 | | /// # Safety |
199 | | /// |
200 | | /// This method is equivalent to `new` except that no runtime assertion is made that `v` |
201 | | /// contains no nul values. Providing a vector with nul values will result in an invalid |
202 | | /// `UCString`. |
203 | 58.9k | pub unsafe fn from_vec_unchecked(v: impl Into<Vec<C>>) -> Self { |
204 | 58.9k | let mut v = v.into(); |
205 | 58.9k | match v.last() { |
206 | 18.5k | None => v.push(UChar::NUL), |
207 | 40.4k | Some(&c) if c != UChar::NUL => v.push(UChar::NUL), |
208 | 0 | Some(_) => (), |
209 | | } |
210 | 58.9k | UCString::from_vec_with_nul_unchecked(v) |
211 | 58.9k | } <widestring::ucstring::UCString<u16>>::from_vec_unchecked::<alloc::vec::Vec<u16>> Line | Count | Source | 203 | 29.9k | pub unsafe fn from_vec_unchecked(v: impl Into<Vec<C>>) -> Self { | 204 | 29.9k | let mut v = v.into(); | 205 | 29.9k | match v.last() { | 206 | 10.2k | None => v.push(UChar::NUL), | 207 | 19.7k | Some(&c) if c != UChar::NUL => v.push(UChar::NUL), | 208 | 0 | Some(_) => (), | 209 | | } | 210 | 29.9k | UCString::from_vec_with_nul_unchecked(v) | 211 | 29.9k | } |
<widestring::ucstring::UCString<u16>>::from_vec_unchecked::<alloc::vec::Vec<u16>> Line | Count | Source | 203 | 28.9k | pub unsafe fn from_vec_unchecked(v: impl Into<Vec<C>>) -> Self { | 204 | 28.9k | let mut v = v.into(); | 205 | 28.9k | match v.last() { | 206 | 8.28k | None => v.push(UChar::NUL), | 207 | 20.6k | Some(&c) if c != UChar::NUL => v.push(UChar::NUL), | 208 | 0 | Some(_) => (), | 209 | | } | 210 | 28.9k | UCString::from_vec_with_nul_unchecked(v) | 211 | 28.9k | } |
Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::from_vec_unchecked::<alloc::vec::Vec<u32>> Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::from_vec_unchecked::<&[u32]> Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::from_vec_unchecked::<alloc::vec::Vec<u16>> Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::from_vec_unchecked::<&[u16]> |
212 | | |
213 | | /// Creates a `UCString` from a vector that should have a nul terminator, without checking |
214 | | /// for any nul values. |
215 | | /// |
216 | | /// # Safety |
217 | | /// |
218 | | /// This method is equivalent to `from_vec_with_nul` except that no runtime assertion is made |
219 | | /// that `v` contains no nul values. Providing a vector with interior nul values or without a |
220 | | /// terminating nul value will result in an invalid `UCString`. |
221 | 58.9k | pub unsafe fn from_vec_with_nul_unchecked(v: impl Into<Vec<C>>) -> Self { |
222 | 58.9k | UCString { |
223 | 58.9k | inner: v.into().into_boxed_slice(), |
224 | 58.9k | } |
225 | 58.9k | } <widestring::ucstring::UCString<u16>>::from_vec_with_nul_unchecked::<alloc::vec::Vec<u16>> Line | Count | Source | 221 | 29.9k | pub unsafe fn from_vec_with_nul_unchecked(v: impl Into<Vec<C>>) -> Self { | 222 | 29.9k | UCString { | 223 | 29.9k | inner: v.into().into_boxed_slice(), | 224 | 29.9k | } | 225 | 29.9k | } |
<widestring::ucstring::UCString<u16>>::from_vec_with_nul_unchecked::<alloc::vec::Vec<u16>> Line | Count | Source | 221 | 28.9k | pub unsafe fn from_vec_with_nul_unchecked(v: impl Into<Vec<C>>) -> Self { | 222 | 28.9k | UCString { | 223 | 28.9k | inner: v.into().into_boxed_slice(), | 224 | 28.9k | } | 225 | 28.9k | } |
Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::from_vec_with_nul_unchecked::<alloc::vec::Vec<u32>> Unexecuted instantiation: <widestring::ucstring::UCString<u32>>::from_vec_with_nul_unchecked::<&[u32]> Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::from_vec_with_nul_unchecked::<alloc::vec::Vec<u16>> Unexecuted instantiation: <widestring::ucstring::UCString<u16>>::from_vec_with_nul_unchecked::<&[u16]> |
226 | | |
227 | | /// Constructs a `UCString` from anything that can be converted to a `UStr`. |
228 | | /// |
229 | | /// The string will be scanned for invalid nul values. |
230 | | /// |
231 | | /// # Failures |
232 | | /// |
233 | | /// This function will return an error if the data contains a nul value. |
234 | | /// The returned error will contain a `Vec` as well as the position of the nul value. |
235 | 0 | pub fn from_ustr(s: impl AsRef<UStr<C>>) -> Result<Self, NulError<C>> { |
236 | 0 | UCString::new(s.as_ref().as_slice()) |
237 | 0 | } |
238 | | |
239 | | /// Constructs a `UCString` from anything that can be converted to a `UStr`, without |
240 | | /// scanning for invalid nul values. |
241 | | /// |
242 | | /// # Safety |
243 | | /// |
244 | | /// This method is equivalent to `from_u16_str` except that no runtime assertion is made that |
245 | | /// `s` contains no nul values. Providing a string with nul values will result in an invalid |
246 | | /// `UCString`. |
247 | 0 | pub unsafe fn from_ustr_unchecked(s: impl AsRef<UStr<C>>) -> Self { |
248 | 0 | UCString::from_vec_unchecked(s.as_ref().as_slice()) |
249 | 0 | } |
250 | | |
251 | | /// Constructs a `UCString` from anything that can be converted to a `UStr` with a nul |
252 | | /// terminator. |
253 | | /// |
254 | | /// The string will be truncated at the first nul value in the string. |
255 | | /// |
256 | | /// # Failures |
257 | | /// |
258 | | /// This function will return an error if the data does not contain a nul to terminate the |
259 | | /// string. The returned error will contain the consumed `Vec`. |
260 | 0 | pub fn from_ustr_with_nul(s: impl AsRef<UStr<C>>) -> Result<Self, MissingNulError<C>> { |
261 | 0 | UCString::from_vec_with_nul(s.as_ref().as_slice()) |
262 | 0 | } |
263 | | |
264 | | /// Constructs a `UCString` from anything that can be converted to a `UStr` with a nul |
265 | | /// terminator, without checking the string for any invalid interior nul values. |
266 | | /// |
267 | | /// # Safety |
268 | | /// |
269 | | /// This method is equivalent to `from_u16_str_with_nul` except that no runtime assertion is |
270 | | /// made that `s` contains no nul values. Providing a vector with interior nul values or |
271 | | /// without a terminating nul value will result in an invalid `UCString`. |
272 | 0 | pub unsafe fn from_ustr_with_nul_unchecked(s: impl AsRef<UStr<C>>) -> Self { |
273 | 0 | UCString::from_vec_with_nul_unchecked(s.as_ref().as_slice()) |
274 | 0 | } |
275 | | |
276 | | /// Constructs a new `UCString` copied from a nul-terminated string pointer. |
277 | | /// |
278 | | /// This will scan for nul values beginning with `p`. The first nul value will be used as the |
279 | | /// nul terminator for the string, similar to how libc string functions such as `strlen` work. |
280 | | /// |
281 | | /// # Safety |
282 | | /// |
283 | | /// This function is unsafe as there is no guarantee that the given pointer is valid or has a |
284 | | /// nul terminator, and the function could scan past the underlying buffer. |
285 | | /// |
286 | | /// `p` must be non-null. |
287 | | /// |
288 | | /// # Panics |
289 | | /// |
290 | | /// This function panics if `p` is null. |
291 | | /// |
292 | | /// # Caveat |
293 | | /// |
294 | | /// The lifetime for the returned string is inferred from its usage. To prevent accidental |
295 | | /// misuse, it's suggested to tie the lifetime to whichever source lifetime is safe in the |
296 | | /// context, such as by providing a helper function taking the lifetime of a host value for the |
297 | | /// string, or by explicit annotation. |
298 | 0 | pub unsafe fn from_ptr_str(p: *const C) -> Self { |
299 | 0 | assert!(!p.is_null()); |
300 | 0 | let mut i: isize = 0; |
301 | 0 | while *p.offset(i) != UChar::NUL { |
302 | 0 | i += 1; |
303 | 0 | } |
304 | 0 | let slice = slice::from_raw_parts(p, i as usize + 1); |
305 | 0 | UCString::from_vec_with_nul_unchecked(slice) |
306 | 0 | } |
307 | | |
308 | | /// Converts to a `UCStr` reference. |
309 | 0 | pub fn as_ucstr(&self) -> &UCStr<C> { |
310 | 0 | self |
311 | 0 | } |
312 | | |
313 | | /// Converts the wide string into a `Vec` without a nul terminator, consuming the string in |
314 | | /// the process. |
315 | | /// |
316 | | /// The resulting vector will **not** contain a nul-terminator, and will contain no other nul |
317 | | /// values. |
318 | 0 | pub fn into_vec(self) -> Vec<C> { |
319 | 0 | let mut v = self.into_inner().into_vec(); |
320 | 0 | v.pop(); |
321 | 0 | v |
322 | 0 | } |
323 | | |
324 | | /// Converts the wide string into a `Vec`, consuming the string in the process. |
325 | | /// |
326 | | /// The resulting vector will contain a nul-terminator and no interior nul values. |
327 | 0 | pub fn into_vec_with_nul(self) -> Vec<C> { |
328 | 0 | self.into_inner().into_vec() |
329 | 0 | } |
330 | | |
331 | | /// Transfers ownership of the wide string to a C caller. |
332 | | /// |
333 | | /// # Safety |
334 | | /// |
335 | | /// The pointer must be returned to Rust and reconstituted using `from_raw` to be properly |
336 | | /// deallocated. Specifically, one should _not_ use the standard C `free` function to |
337 | | /// deallocate this string. |
338 | | /// |
339 | | /// Failure to call `from_raw` will lead to a memory leak. |
340 | 0 | pub fn into_raw(self) -> *mut C { |
341 | 0 | Box::into_raw(self.into_inner()) as *mut C |
342 | 0 | } |
343 | | |
344 | | /// Retakes ownership of a `UCString` that was transferred to C. |
345 | | /// |
346 | | /// # Safety |
347 | | /// |
348 | | /// This should only ever be called with a pointer that was earlier obtained by calling |
349 | | /// `into_raw` on a `UCString`. Additionally, the length of the string will be recalculated |
350 | | /// from the pointer. |
351 | 0 | pub unsafe fn from_raw(p: *mut C) -> Self { |
352 | 0 | assert!(!p.is_null()); |
353 | 0 | let mut i: isize = 0; |
354 | 0 | while *p.offset(i) != UChar::NUL { |
355 | 0 | i += 1; |
356 | 0 | } |
357 | 0 | let slice = slice::from_raw_parts_mut(p, i as usize + 1); |
358 | 0 | UCString { |
359 | 0 | inner: mem::transmute(slice), |
360 | 0 | } |
361 | 0 | } |
362 | | |
363 | | /// Converts this `UCString` into a boxed `UCStr`. |
364 | | /// |
365 | | /// # Examples |
366 | | /// |
367 | | /// ``` |
368 | | /// use widestring::{U16CString, U16CStr}; |
369 | | /// |
370 | | /// let mut v = vec![102u16, 111u16, 111u16]; // "foo" |
371 | | /// let c_string = U16CString::new(v.clone()).unwrap(); |
372 | | /// let boxed = c_string.into_boxed_ucstr(); |
373 | | /// v.push(0); |
374 | | /// assert_eq!(&*boxed, U16CStr::from_slice_with_nul(&v).unwrap()); |
375 | | /// ``` |
376 | | /// |
377 | | /// ``` |
378 | | /// use widestring::{U32CString, U32CStr}; |
379 | | /// |
380 | | /// let mut v = vec![102u32, 111u32, 111u32]; // "foo" |
381 | | /// let c_string = U32CString::new(v.clone()).unwrap(); |
382 | | /// let boxed = c_string.into_boxed_ucstr(); |
383 | | /// v.push(0); |
384 | | /// assert_eq!(&*boxed, U32CStr::from_slice_with_nul(&v).unwrap()); |
385 | | /// ``` |
386 | 0 | pub fn into_boxed_ucstr(self) -> Box<UCStr<C>> { |
387 | 0 | unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut UCStr<C>) } |
388 | 0 | } |
389 | | |
390 | | /// Bypass "move out of struct which implements [`Drop`] trait" restriction. |
391 | | /// |
392 | | /// [`Drop`]: ../ops/trait.Drop.html |
393 | 0 | fn into_inner(self) -> Box<[C]> { |
394 | | unsafe { |
395 | 0 | let result = ptr::read(&self.inner); |
396 | 0 | mem::forget(self); |
397 | 0 | result |
398 | | } |
399 | 0 | } |
400 | | } |
401 | | |
402 | | impl UCString<u16> { |
403 | | /// Constructs a `U16CString` from a `str`. |
404 | | /// |
405 | | /// The string will be scanned for invalid nul values. |
406 | | /// |
407 | | /// # Failures |
408 | | /// |
409 | | /// This function will return an error if the data contains a nul value. |
410 | | /// The returned error will contain a `Vec<u16>` as well as the position of the nul value. |
411 | | /// |
412 | | /// # Examples |
413 | | /// |
414 | | /// ```rust |
415 | | /// use widestring::U16CString; |
416 | | /// let s = "MyString"; |
417 | | /// // Create a wide string from the string |
418 | | /// let wcstr = U16CString::from_str(s).unwrap(); |
419 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
420 | | /// ``` |
421 | | /// |
422 | | /// The following example demonstrates errors from nul values in a vector. |
423 | | /// |
424 | | /// ```rust |
425 | | /// use widestring::U16CString; |
426 | | /// let s = "My\u{0}String"; |
427 | | /// // Create a wide string from the string |
428 | | /// let res = U16CString::from_str(s); |
429 | | /// assert!(res.is_err()); |
430 | | /// assert_eq!(res.err().unwrap().nul_position(), 2); |
431 | | /// ``` |
432 | | #[allow(clippy::should_implement_trait)] |
433 | 0 | pub fn from_str(s: impl AsRef<str>) -> Result<Self, NulError<u16>> { |
434 | 0 | let v: Vec<u16> = s.as_ref().encode_utf16().collect(); |
435 | 0 | UCString::new(v) |
436 | 0 | } |
437 | | |
438 | | /// Constructs a `U16CString` from a `str`, without checking for interior nul values. |
439 | | /// |
440 | | /// # Safety |
441 | | /// |
442 | | /// This method is equivalent to `from_str` except that no runtime assertion is made that `s` |
443 | | /// contains no nul values. Providing a string with nul values will result in an invalid |
444 | | /// `U16CString`. |
445 | | /// |
446 | | /// # Examples |
447 | | /// |
448 | | /// ```rust |
449 | | /// use widestring::U16CString; |
450 | | /// let s = "MyString"; |
451 | | /// // Create a wide string from the string |
452 | | /// let wcstr = unsafe { U16CString::from_str_unchecked(s) }; |
453 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
454 | | /// ``` |
455 | 0 | pub unsafe fn from_str_unchecked(s: impl AsRef<str>) -> Self { |
456 | 0 | let v: Vec<u16> = s.as_ref().encode_utf16().collect(); |
457 | 0 | UCString::from_vec_unchecked(v) |
458 | 0 | } |
459 | | |
460 | | /// Constructs a `U16CString` from a `str` with a nul terminator. |
461 | | /// |
462 | | /// The string will be truncated at the first nul value in the string. |
463 | | /// |
464 | | /// # Failures |
465 | | /// |
466 | | /// This function will return an error if the data does not contain a nul to terminate the |
467 | | /// string. The returned error will contain the consumed `Vec<u16>`. |
468 | | /// |
469 | | /// # Examples |
470 | | /// |
471 | | /// ```rust |
472 | | /// use widestring::U16CString; |
473 | | /// let s = "My\u{0}String"; |
474 | | /// // Create a wide string from the string |
475 | | /// let wcstr = U16CString::from_str_with_nul(s).unwrap(); |
476 | | /// assert_eq!(wcstr.to_string_lossy(), "My"); |
477 | | /// ``` |
478 | | /// |
479 | | /// The following example demonstrates errors from missing nul values in a vector. |
480 | | /// |
481 | | /// ```rust |
482 | | /// use widestring::U16CString; |
483 | | /// let s = "MyString"; |
484 | | /// // Create a wide string from the string |
485 | | /// let res = U16CString::from_str_with_nul(s); |
486 | | /// assert!(res.is_err()); |
487 | | /// ``` |
488 | 0 | pub fn from_str_with_nul(s: impl AsRef<str>) -> Result<Self, MissingNulError<u16>> { |
489 | 0 | let v: Vec<u16> = s.as_ref().encode_utf16().collect(); |
490 | 0 | UCString::from_vec_with_nul(v) |
491 | 0 | } |
492 | | |
493 | | /// Constructs a `U16CString` from str `str` that should have a terminating nul, but without |
494 | | /// checking for any nul values. |
495 | | /// |
496 | | /// # Safety |
497 | | /// |
498 | | /// This method is equivalent to `from_str_with_nul` except that no runtime assertion is made |
499 | | /// that `s` contains no nul values. Providing a vector with interior nul values or without a |
500 | | /// terminating nul value will result in an invalid `U16CString`. |
501 | | /// |
502 | | /// # Examples |
503 | | /// |
504 | | /// ```rust |
505 | | /// use widestring::U16CString; |
506 | | /// let s = "My String\u{0}"; |
507 | | /// // Create a wide string from the string |
508 | | /// let wcstr = unsafe { U16CString::from_str_with_nul_unchecked(s) }; |
509 | | /// assert_eq!(wcstr.to_string_lossy(), "My String"); |
510 | | /// ``` |
511 | 0 | pub unsafe fn from_str_with_nul_unchecked(s: impl AsRef<str>) -> Self { |
512 | 0 | let v: Vec<u16> = s.as_ref().encode_utf16().collect(); |
513 | 0 | UCString::from_vec_with_nul_unchecked(v) |
514 | 0 | } |
515 | | |
516 | | /// Constructs a new `U16CString` copied from a `u16` pointer and a length. |
517 | | /// |
518 | | /// The `len` argument is the number of `u16` elements, **not** the number of bytes. |
519 | | /// |
520 | | /// The string will be scanned for invalid nul values. |
521 | | /// |
522 | | /// # Failures |
523 | | /// |
524 | | /// This function will return an error if the data contains a nul value. |
525 | | /// The returned error will contain a `Vec<u16>` as well as the position of the nul value. |
526 | | /// |
527 | | /// # Safety |
528 | | /// |
529 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
530 | | /// elements. |
531 | | /// |
532 | | /// # Panics |
533 | | /// |
534 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
535 | 0 | pub unsafe fn from_ptr(p: *const u16, len: usize) -> Result<Self, NulError<u16>> { |
536 | 0 | if len == 0 { |
537 | 0 | return Ok(UCString::default()); |
538 | 0 | } |
539 | 0 | assert!(!p.is_null()); |
540 | 0 | let slice = slice::from_raw_parts(p, len); |
541 | 0 | UCString::new(slice) |
542 | 0 | } |
543 | | |
544 | | /// Constructs a new `U16CString` copied from a `u16` pointer and a length. |
545 | | /// |
546 | | /// The `len` argument is the number of `u16` elements, **not** the number of bytes. |
547 | | /// |
548 | | /// The string will **not** be checked for invalid nul values. |
549 | | /// |
550 | | /// # Safety |
551 | | /// |
552 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
553 | | /// elements. In addition, no checking for invalid nul values is performed, so if any elements |
554 | | /// of `p` are a nul value, the resulting `U16CString` will be invalid. |
555 | | /// |
556 | | /// # Panics |
557 | | /// |
558 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
559 | 0 | pub unsafe fn from_ptr_unchecked(p: *const u16, len: usize) -> Self { |
560 | 0 | if len == 0 { |
561 | 0 | return UCString::default(); |
562 | 0 | } |
563 | 0 | assert!(!p.is_null()); |
564 | 0 | let slice = slice::from_raw_parts(p, len); |
565 | 0 | UCString::from_vec_unchecked(slice) |
566 | 0 | } |
567 | | |
568 | | /// Constructs a new `U16String` copied from a `u16` pointer and a length. |
569 | | /// |
570 | | /// The `len` argument is the number of `u16` elements, **not** the number of bytes. |
571 | | /// |
572 | | /// The string will be truncated at the first nul value in the string. |
573 | | /// |
574 | | /// # Failures |
575 | | /// |
576 | | /// This function will return an error if the data does not contain a nul to terminate the |
577 | | /// string. The returned error will contain the consumed `Vec<u16>`. |
578 | | /// |
579 | | /// # Safety |
580 | | /// |
581 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
582 | | /// elements. |
583 | | /// |
584 | | /// # Panics |
585 | | /// |
586 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
587 | 0 | pub unsafe fn from_ptr_with_nul( |
588 | 0 | p: *const u16, |
589 | 0 | len: usize, |
590 | 0 | ) -> Result<Self, MissingNulError<u16>> { |
591 | 0 | if len == 0 { |
592 | 0 | return Ok(UCString::default()); |
593 | 0 | } |
594 | 0 | assert!(!p.is_null()); |
595 | 0 | let slice = slice::from_raw_parts(p, len); |
596 | 0 | UCString::from_vec_with_nul(slice) |
597 | 0 | } |
598 | | |
599 | | /// Constructs a new `U16String` copied from a `u16` pointer and a length. |
600 | | /// |
601 | | /// The `len` argument is the number of `u16` elements, **not** the number of bytes. |
602 | | /// |
603 | | /// The data should end with a nul terminator, but no checking is done on whether the data |
604 | | /// actually ends with a nul terminator, or if the data contains any interior nul values. |
605 | | /// |
606 | | /// # Safety |
607 | | /// |
608 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
609 | | /// elements. In addition, no checking for nul values is performed, so if there data does not |
610 | | /// end with a nul terminator, or if there are any interior nul values, the resulting |
611 | | /// `U16CString` will be invalid. |
612 | | /// |
613 | | /// # Panics |
614 | | /// |
615 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
616 | 0 | pub unsafe fn from_ptr_with_nul_unchecked(p: *const u16, len: usize) -> Self { |
617 | 0 | if len == 0 { |
618 | 0 | return UCString::default(); |
619 | 0 | } |
620 | 0 | assert!(!p.is_null()); |
621 | 0 | let slice = slice::from_raw_parts(p, len); |
622 | 0 | UCString::from_vec_with_nul_unchecked(slice) |
623 | 0 | } |
624 | | |
625 | | /// Constructs a `U16CString` from anything that can be converted to an `OsStr`. |
626 | | /// |
627 | | /// The string will be scanned for invalid nul values. |
628 | | /// |
629 | | /// # Failures |
630 | | /// |
631 | | /// This function will return an error if the data contains a nul value. |
632 | | /// The returned error will contain a `Vec<u16>` as well as the position of the nul value. |
633 | | /// |
634 | | /// # Examples |
635 | | /// |
636 | | /// ```rust |
637 | | /// use widestring::U16CString; |
638 | | /// let s = "MyString"; |
639 | | /// // Create a wide string from the string |
640 | | /// let wcstr = U16CString::from_os_str(s).unwrap(); |
641 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
642 | | /// ``` |
643 | | /// |
644 | | /// The following example demonstrates errors from nul values in a vector. |
645 | | /// |
646 | | /// ```rust |
647 | | /// use widestring::U16CString; |
648 | | /// let s = "My\u{0}String"; |
649 | | /// // Create a wide string from the string |
650 | | /// let res = U16CString::from_os_str(s); |
651 | | /// assert!(res.is_err()); |
652 | | /// assert_eq!(res.err().unwrap().nul_position(), 2); |
653 | | /// ``` |
654 | | #[cfg(feature = "std")] |
655 | 0 | pub fn from_os_str(s: impl AsRef<std::ffi::OsStr>) -> Result<Self, NulError<u16>> { |
656 | 0 | let v = crate::platform::os_to_wide(s.as_ref()); |
657 | 0 | UCString::new(v) |
658 | 0 | } |
659 | | |
660 | | /// Constructs a `U16CString` from anything that can be converted to an `OsStr`, without |
661 | | /// checking for interior nul values. |
662 | | /// |
663 | | /// # Safety |
664 | | /// |
665 | | /// This method is equivalent to `from_os_str` except that no runtime assertion is made that |
666 | | /// `s` contains no nul values. Providing a string with nul values will result in an invalid |
667 | | /// `U16CString`. |
668 | | /// |
669 | | /// # Examples |
670 | | /// |
671 | | /// ```rust |
672 | | /// use widestring::U16CString; |
673 | | /// let s = "MyString"; |
674 | | /// // Create a wide string from the string |
675 | | /// let wcstr = unsafe { U16CString::from_os_str_unchecked(s) }; |
676 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
677 | | /// ``` |
678 | | #[cfg(feature = "std")] |
679 | 0 | pub unsafe fn from_os_str_unchecked(s: impl AsRef<std::ffi::OsStr>) -> Self { |
680 | 0 | let v = crate::platform::os_to_wide(s.as_ref()); |
681 | 0 | UCString::from_vec_unchecked(v) |
682 | 0 | } |
683 | | |
684 | | /// Constructs a `U16CString` from anything that can be converted to an `OsStr` with a nul |
685 | | /// terminator. |
686 | | /// |
687 | | /// The string will be truncated at the first nul value in the string. |
688 | | /// |
689 | | /// # Failures |
690 | | /// |
691 | | /// This function will return an error if the data does not contain a nul to terminate the |
692 | | /// string. The returned error will contain the consumed `Vec<u16>`. |
693 | | /// |
694 | | /// # Examples |
695 | | /// |
696 | | /// ```rust |
697 | | /// use widestring::U16CString; |
698 | | /// let s = "My\u{0}String"; |
699 | | /// // Create a wide string from the string |
700 | | /// let wcstr = U16CString::from_os_str_with_nul(s).unwrap(); |
701 | | /// assert_eq!(wcstr.to_string_lossy(), "My"); |
702 | | /// ``` |
703 | | /// |
704 | | /// The following example demonstrates errors from missing nul values in a vector. |
705 | | /// |
706 | | /// ```rust |
707 | | /// use widestring::U16CString; |
708 | | /// let s = "MyString"; |
709 | | /// // Create a wide string from the string |
710 | | /// let res = U16CString::from_os_str_with_nul(s); |
711 | | /// assert!(res.is_err()); |
712 | | /// ``` |
713 | | #[cfg(feature = "std")] |
714 | 0 | pub fn from_os_str_with_nul( |
715 | 0 | s: impl AsRef<std::ffi::OsStr>, |
716 | 0 | ) -> Result<Self, MissingNulError<u16>> { |
717 | 0 | let v = crate::platform::os_to_wide(s.as_ref()); |
718 | 0 | UCString::from_vec_with_nul(v) |
719 | 0 | } |
720 | | |
721 | | /// Constructs a `U16CString` from anything that can be converted to an `OsStr` that should |
722 | | /// have a terminating nul, but without checking for any nul values. |
723 | | /// |
724 | | /// # Safety |
725 | | /// |
726 | | /// This method is equivalent to `from_os_str_with_nul` except that no runtime assertion is |
727 | | /// made that `s` contains no nul values. Providing a vector with interior nul values or |
728 | | /// without a terminating nul value will result in an invalid `U16CString`. |
729 | | /// |
730 | | /// # Examples |
731 | | /// |
732 | | /// ```rust |
733 | | /// use widestring::U16CString; |
734 | | /// let s = "My String\u{0}"; |
735 | | /// // Create a wide string from the string |
736 | | /// let wcstr = unsafe { U16CString::from_os_str_with_nul_unchecked(s) }; |
737 | | /// assert_eq!(wcstr.to_string_lossy(), "My String"); |
738 | | /// ``` |
739 | | #[cfg(feature = "std")] |
740 | 0 | pub unsafe fn from_os_str_with_nul_unchecked(s: impl AsRef<std::ffi::OsStr>) -> Self { |
741 | 0 | let v = crate::platform::os_to_wide(s.as_ref()); |
742 | 0 | UCString::from_vec_with_nul_unchecked(v) |
743 | 0 | } |
744 | | } |
745 | | |
746 | | impl UCString<u32> { |
747 | | /// Constructs a `U32CString` from a container of wide character data. |
748 | | /// |
749 | | /// This method will consume the provided data and use the underlying elements to construct a |
750 | | /// new string. The data will be scanned for invalid nul values. |
751 | | /// |
752 | | /// # Failures |
753 | | /// |
754 | | /// This function will return an error if the data contains a nul value. |
755 | | /// The returned error will contain the `Vec<u32>` as well as the position of the nul value. |
756 | | /// |
757 | | /// # Examples |
758 | | /// |
759 | | /// ```rust |
760 | | /// use widestring::U32CString; |
761 | | /// let v: Vec<char> = "Test".chars().collect(); |
762 | | /// # let cloned: Vec<u32> = v.iter().map(|&c| c as u32).collect(); |
763 | | /// // Create a wide string from the vector |
764 | | /// let wcstr = U32CString::from_chars(v).unwrap(); |
765 | | /// # assert_eq!(wcstr.into_vec(), cloned); |
766 | | /// ``` |
767 | | /// |
768 | | /// The following example demonstrates errors from nul values in a vector. |
769 | | /// |
770 | | /// ```rust |
771 | | /// use widestring::U32CString; |
772 | | /// let v: Vec<char> = "T\u{0}est".chars().collect(); |
773 | | /// // Create a wide string from the vector |
774 | | /// let res = U32CString::from_chars(v); |
775 | | /// assert!(res.is_err()); |
776 | | /// assert_eq!(res.err().unwrap().nul_position(), 1); |
777 | | /// ``` |
778 | 0 | pub fn from_chars(v: impl Into<Vec<char>>) -> Result<Self, NulError<u32>> { |
779 | 0 | let mut chars = v.into(); |
780 | 0 | let v: Vec<u32> = unsafe { |
781 | 0 | let ptr = chars.as_mut_ptr() as *mut u32; |
782 | 0 | let len = chars.len(); |
783 | 0 | let cap = chars.capacity(); |
784 | 0 | ManuallyDrop::new(chars); |
785 | 0 | Vec::from_raw_parts(ptr, len, cap) |
786 | | }; |
787 | 0 | UCString::new(v) |
788 | 0 | } |
789 | | |
790 | | /// Constructs a `U32CString` from a nul-terminated container of UTF-32 data. |
791 | | /// |
792 | | /// This method will consume the provided data and use the underlying elements to construct a |
793 | | /// new string. The string will be truncated at the first nul value in the string. |
794 | | /// |
795 | | /// # Failures |
796 | | /// |
797 | | /// This function will return an error if the data does not contain a nul to terminate the |
798 | | /// string. The returned error will contain the consumed `Vec<u32>`. |
799 | | /// |
800 | | /// # Examples |
801 | | /// |
802 | | /// ```rust |
803 | | /// use widestring::U32CString; |
804 | | /// let v: Vec<char> = "Test\u{0}".chars().collect(); |
805 | | /// # let cloned: Vec<u32> = v[..4].iter().map(|&c| c as u32).collect(); |
806 | | /// // Create a wide string from the vector |
807 | | /// let wcstr = U32CString::from_chars_with_nul(v).unwrap(); |
808 | | /// # assert_eq!(wcstr.into_vec(), cloned); |
809 | | /// ``` |
810 | | /// |
811 | | /// The following example demonstrates errors from missing nul values in a vector. |
812 | | /// |
813 | | /// ```rust |
814 | | /// use widestring::U32CString; |
815 | | /// let v: Vec<char> = "Test".chars().collect(); |
816 | | /// // Create a wide string from the vector |
817 | | /// let res = U32CString::from_chars_with_nul(v); |
818 | | /// assert!(res.is_err()); |
819 | | /// ``` |
820 | 0 | pub fn from_chars_with_nul(v: impl Into<Vec<char>>) -> Result<Self, MissingNulError<u32>> { |
821 | 0 | let mut chars = v.into(); |
822 | 0 | let v: Vec<u32> = unsafe { |
823 | 0 | let ptr = chars.as_mut_ptr() as *mut u32; |
824 | 0 | let len = chars.len(); |
825 | 0 | let cap = chars.capacity(); |
826 | 0 | ManuallyDrop::new(chars); |
827 | 0 | Vec::from_raw_parts(ptr, len, cap) |
828 | | }; |
829 | 0 | UCString::from_vec_with_nul(v) |
830 | 0 | } |
831 | | |
832 | | /// Creates a `U32CString` from a vector without checking for interior nul values. |
833 | | /// |
834 | | /// A terminating nul value will be appended if the vector does not already have a terminating |
835 | | /// nul. |
836 | | /// |
837 | | /// # Safety |
838 | | /// |
839 | | /// This method is equivalent to `new` except that no runtime assertion is made that `v` |
840 | | /// contains no nul values. Providing a vector with nul values will result in an invalid |
841 | | /// `U32CString`. |
842 | 0 | pub unsafe fn from_chars_unchecked(v: impl Into<Vec<char>>) -> Self { |
843 | 0 | let mut chars = v.into(); |
844 | 0 | let v: Vec<u32> = { |
845 | 0 | let ptr = chars.as_mut_ptr() as *mut u32; |
846 | 0 | let len = chars.len(); |
847 | 0 | let cap = chars.capacity(); |
848 | 0 | ManuallyDrop::new(chars); |
849 | 0 | Vec::from_raw_parts(ptr, len, cap) |
850 | | }; |
851 | 0 | UCString::from_vec_unchecked(v) |
852 | 0 | } |
853 | | |
854 | | /// Creates a `U32CString` from a vector that should have a nul terminator, without checking |
855 | | /// for any nul values. |
856 | | /// |
857 | | /// # Safety |
858 | | /// |
859 | | /// This method is equivalent to `from_vec_with_nul` except that no runtime assertion is made |
860 | | /// that `v` contains no nul values. Providing a vector with interior nul values or without a |
861 | | /// terminating nul value will result in an invalid `U32CString`. |
862 | 0 | pub unsafe fn from_chars_with_nul_unchecked(v: impl Into<Vec<char>>) -> Self { |
863 | 0 | let mut chars = v.into(); |
864 | 0 | let v: Vec<u32> = { |
865 | 0 | let ptr = chars.as_mut_ptr() as *mut u32; |
866 | 0 | let len = chars.len(); |
867 | 0 | let cap = chars.capacity(); |
868 | 0 | ManuallyDrop::new(chars); |
869 | 0 | Vec::from_raw_parts(ptr, len, cap) |
870 | | }; |
871 | 0 | UCString::from_vec_with_nul_unchecked(v) |
872 | 0 | } |
873 | | |
874 | | /// Constructs a `U32CString` from a `str`. |
875 | | /// |
876 | | /// The string will be scanned for invalid nul values. |
877 | | /// |
878 | | /// # Failures |
879 | | /// |
880 | | /// This function will return an error if the data contains a nul value. |
881 | | /// The returned error will contain a `Vec<u32>` as well as the position of the nul value. |
882 | | /// |
883 | | /// # Examples |
884 | | /// |
885 | | /// ```rust |
886 | | /// use widestring::U32CString; |
887 | | /// let s = "MyString"; |
888 | | /// // Create a wide string from the string |
889 | | /// let wcstr = U32CString::from_str(s).unwrap(); |
890 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
891 | | /// ``` |
892 | | /// |
893 | | /// The following example demonstrates errors from nul values in a vector. |
894 | | /// |
895 | | /// ```rust |
896 | | /// use widestring::U32CString; |
897 | | /// let s = "My\u{0}String"; |
898 | | /// // Create a wide string from the string |
899 | | /// let res = U32CString::from_str(s); |
900 | | /// assert!(res.is_err()); |
901 | | /// assert_eq!(res.err().unwrap().nul_position(), 2); |
902 | | /// ``` |
903 | | #[allow(clippy::should_implement_trait)] |
904 | 0 | pub fn from_str(s: impl AsRef<str>) -> Result<Self, NulError<u32>> { |
905 | 0 | let v: Vec<char> = s.as_ref().chars().collect(); |
906 | 0 | UCString::from_chars(v) |
907 | 0 | } |
908 | | |
909 | | /// Constructs a `U32CString` from a `str`, without checking for interior nul values. |
910 | | /// |
911 | | /// # Safety |
912 | | /// |
913 | | /// This method is equivalent to `from_str` except that no runtime assertion is made that `s` |
914 | | /// contains no nul values. Providing a string with nul values will result in an invalid |
915 | | /// `U32CString`. |
916 | | /// |
917 | | /// # Examples |
918 | | /// |
919 | | /// ```rust |
920 | | /// use widestring::U32CString; |
921 | | /// let s = "MyString"; |
922 | | /// // Create a wide string from the string |
923 | | /// let wcstr = unsafe { U32CString::from_str_unchecked(s) }; |
924 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
925 | | /// ``` |
926 | 0 | pub unsafe fn from_str_unchecked(s: impl AsRef<str>) -> Self { |
927 | 0 | let v: Vec<char> = s.as_ref().chars().collect(); |
928 | 0 | UCString::from_chars_unchecked(v) |
929 | 0 | } |
930 | | |
931 | | /// Constructs a `U32CString` from a `str` with a nul terminator. |
932 | | /// |
933 | | /// The string will be truncated at the first nul value in the string. |
934 | | /// |
935 | | /// # Failures |
936 | | /// |
937 | | /// This function will return an error if the data does not contain a nul to terminate the |
938 | | /// string. The returned error will contain the consumed `Vec<u32>`. |
939 | | /// |
940 | | /// # Examples |
941 | | /// |
942 | | /// ```rust |
943 | | /// use widestring::U32CString; |
944 | | /// let s = "My\u{0}String"; |
945 | | /// // Create a wide string from the string |
946 | | /// let wcstr = U32CString::from_str_with_nul(s).unwrap(); |
947 | | /// assert_eq!(wcstr.to_string_lossy(), "My"); |
948 | | /// ``` |
949 | | /// |
950 | | /// The following example demonstrates errors from missing nul values in a vector. |
951 | | /// |
952 | | /// ```rust |
953 | | /// use widestring::U32CString; |
954 | | /// let s = "MyString"; |
955 | | /// // Create a wide string from the string |
956 | | /// let res = U32CString::from_str_with_nul(s); |
957 | | /// assert!(res.is_err()); |
958 | | /// ``` |
959 | 0 | pub fn from_str_with_nul(s: impl AsRef<str>) -> Result<Self, MissingNulError<u32>> { |
960 | 0 | let v: Vec<char> = s.as_ref().chars().collect(); |
961 | 0 | UCString::from_chars_with_nul(v) |
962 | 0 | } |
963 | | |
964 | | /// Constructs a `U32CString` from a `str` that should have a terminating nul, but without |
965 | | /// checking for any nul values. |
966 | | /// |
967 | | /// # Safety |
968 | | /// |
969 | | /// This method is equivalent to `from_str_with_nul` except that no runtime assertion is made |
970 | | /// that `s` contains no nul values. Providing a vector with interior nul values or without a |
971 | | /// terminating nul value will result in an invalid `U32CString`. |
972 | | /// |
973 | | /// # Examples |
974 | | /// |
975 | | /// ```rust |
976 | | /// use widestring::U32CString; |
977 | | /// let s = "My String\u{0}"; |
978 | | /// // Create a wide string from the string |
979 | | /// let wcstr = unsafe { U32CString::from_str_with_nul_unchecked(s) }; |
980 | | /// assert_eq!(wcstr.to_string_lossy(), "My String"); |
981 | | /// ``` |
982 | 0 | pub unsafe fn from_str_with_nul_unchecked(s: impl AsRef<str>) -> Self { |
983 | 0 | let v: Vec<char> = s.as_ref().chars().collect(); |
984 | 0 | UCString::from_chars_with_nul_unchecked(v) |
985 | 0 | } |
986 | | |
987 | | /// Constructs a new `U32CString` copied from a `u32` pointer and a length. |
988 | | /// |
989 | | /// The `len` argument is the number of `u32` elements, **not** the number of bytes. |
990 | | /// |
991 | | /// The string will be scanned for invalid nul values. |
992 | | /// |
993 | | /// # Failures |
994 | | /// |
995 | | /// This function will return an error if the data contains a nul value. |
996 | | /// The returned error will contain a `Vec<u32>` as well as the position of the nul value. |
997 | | /// |
998 | | /// # Safety |
999 | | /// |
1000 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1001 | | /// elements. |
1002 | | /// |
1003 | | /// # Panics |
1004 | | /// |
1005 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1006 | 0 | pub unsafe fn from_ptr(p: *const u32, len: usize) -> Result<Self, NulError<u32>> { |
1007 | 0 | if len == 0 { |
1008 | 0 | return Ok(UCString::default()); |
1009 | 0 | } |
1010 | 0 | assert!(!p.is_null()); |
1011 | 0 | let slice = slice::from_raw_parts(p, len); |
1012 | 0 | UCString::new(slice) |
1013 | 0 | } |
1014 | | |
1015 | | /// Constructs a new `U32CString` copied from a `u32` pointer and a length. |
1016 | | /// |
1017 | | /// The `len` argument is the number of `u32` elements, **not** the number of bytes. |
1018 | | /// |
1019 | | /// The string will **not** be checked for invalid nul values. |
1020 | | /// |
1021 | | /// # Safety |
1022 | | /// |
1023 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1024 | | /// elements. In addition, no checking for invalid nul values is performed, so if any elements |
1025 | | /// of `p` are a nul value, the resulting `U16CString` will be invalid. |
1026 | | /// |
1027 | | /// # Panics |
1028 | | /// |
1029 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1030 | 0 | pub unsafe fn from_ptr_unchecked(p: *const u32, len: usize) -> Self { |
1031 | 0 | if len == 0 { |
1032 | 0 | return UCString::default(); |
1033 | 0 | } |
1034 | 0 | assert!(!p.is_null()); |
1035 | 0 | let slice = slice::from_raw_parts(p, len); |
1036 | 0 | UCString::from_vec_unchecked(slice) |
1037 | 0 | } |
1038 | | |
1039 | | /// Constructs a new `U32String` copied from a `u32` pointer and a length. |
1040 | | /// |
1041 | | /// The `len` argument is the number of `u32` elements, **not** the number of bytes. |
1042 | | /// |
1043 | | /// The string will be truncated at the first nul value in the string. |
1044 | | /// |
1045 | | /// # Failures |
1046 | | /// |
1047 | | /// This function will return an error if the data does not contain a nul to terminate the |
1048 | | /// string. The returned error will contain the consumed `Vec<u32>`. |
1049 | | /// |
1050 | | /// # Safety |
1051 | | /// |
1052 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1053 | | /// elements. |
1054 | | /// |
1055 | | /// # Panics |
1056 | | /// |
1057 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1058 | 0 | pub unsafe fn from_ptr_with_nul( |
1059 | 0 | p: *const u32, |
1060 | 0 | len: usize, |
1061 | 0 | ) -> Result<Self, MissingNulError<u32>> { |
1062 | 0 | if len == 0 { |
1063 | 0 | return Ok(UCString::default()); |
1064 | 0 | } |
1065 | 0 | assert!(!p.is_null()); |
1066 | 0 | let slice = slice::from_raw_parts(p, len); |
1067 | 0 | UCString::from_vec_with_nul(slice) |
1068 | 0 | } |
1069 | | |
1070 | | /// Constructs a new `U32String` copied from a `u32` pointer and a length. |
1071 | | /// |
1072 | | /// The `len` argument is the number of `u32` elements, **not** the number of bytes. |
1073 | | /// |
1074 | | /// The data should end with a nul terminator, but no checking is done on whether the data |
1075 | | /// actually ends with a nul terminator, or if the data contains any interior nul values. |
1076 | | /// |
1077 | | /// # Safety |
1078 | | /// |
1079 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1080 | | /// elements. In addition, no checking for nul values is performed, so if there data does not |
1081 | | /// end with a nul terminator, or if there are any interior nul values, the resulting |
1082 | | /// `U32CString` will be invalid. |
1083 | | /// |
1084 | | /// # Panics |
1085 | | /// |
1086 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1087 | 0 | pub unsafe fn from_ptr_with_nul_unchecked(p: *const u32, len: usize) -> Self { |
1088 | 0 | if len == 0 { |
1089 | 0 | return UCString::default(); |
1090 | 0 | } |
1091 | 0 | assert!(!p.is_null()); |
1092 | 0 | let slice = slice::from_raw_parts(p, len); |
1093 | 0 | UCString::from_vec_with_nul_unchecked(slice) |
1094 | 0 | } |
1095 | | |
1096 | | /// Constructs a new `U32CString` copied from a `char` pointer and a length. |
1097 | | /// |
1098 | | /// The `len` argument is the number of `char` elements, **not** the number of bytes. |
1099 | | /// |
1100 | | /// The string will be scanned for invalid nul values. |
1101 | | /// |
1102 | | /// # Failures |
1103 | | /// |
1104 | | /// This function will return an error if the data contains a nul value. |
1105 | | /// The returned error will contain a `Vec<u32>` as well as the position of the nul value. |
1106 | | /// |
1107 | | /// # Safety |
1108 | | /// |
1109 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1110 | | /// elements. |
1111 | | /// |
1112 | | /// # Panics |
1113 | | /// |
1114 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1115 | 0 | pub unsafe fn from_char_ptr(p: *const char, len: usize) -> Result<Self, NulError<u32>> { |
1116 | 0 | UCString::<u32>::from_ptr(p as *const u32, len) |
1117 | 0 | } |
1118 | | |
1119 | | /// Constructs a new `U32CString` copied from a `char` pointer and a length. |
1120 | | /// |
1121 | | /// The `len` argument is the number of `char` elements, **not** the number of bytes. |
1122 | | /// |
1123 | | /// The string will **not** be checked for invalid nul values. |
1124 | | /// |
1125 | | /// # Safety |
1126 | | /// |
1127 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1128 | | /// elements. In addition, no checking for invalid nul values is performed, so if any elements |
1129 | | /// of `p` are a nul value, the resulting `U32CString` will be invalid. |
1130 | | /// |
1131 | | /// # Panics |
1132 | | /// |
1133 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1134 | 0 | pub unsafe fn from_char_ptr_unchecked(p: *const char, len: usize) -> Self { |
1135 | 0 | UCString::<u32>::from_ptr_unchecked(p as *const u32, len) |
1136 | 0 | } |
1137 | | |
1138 | | /// Constructs a new `U32String` copied from a `char` pointer and a length. |
1139 | | /// |
1140 | | /// The `len` argument is the number of `char` elements, **not** the number of bytes. |
1141 | | /// |
1142 | | /// The string will be truncated at the first nul value in the string. |
1143 | | /// |
1144 | | /// # Failures |
1145 | | /// |
1146 | | /// This function will return an error if the data does not contain a nul to terminate the |
1147 | | /// string. The returned error will contain the consumed `Vec<u32>`. |
1148 | | /// |
1149 | | /// # Safety |
1150 | | /// |
1151 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1152 | | /// elements. |
1153 | | /// |
1154 | | /// # Panics |
1155 | | /// |
1156 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1157 | 0 | pub unsafe fn from_char_ptr_with_nul( |
1158 | 0 | p: *const char, |
1159 | 0 | len: usize, |
1160 | 0 | ) -> Result<Self, MissingNulError<u32>> { |
1161 | 0 | UCString::<u32>::from_ptr_with_nul(p as *const u32, len) |
1162 | 0 | } |
1163 | | |
1164 | | /// Constructs a new `U32String` copied from a `char` pointer and a length. |
1165 | | /// |
1166 | | /// The `len` argument is the number of `char` elements, **not** the number of bytes. |
1167 | | /// |
1168 | | /// The data should end with a nul terminator, but no checking is done on whether the data |
1169 | | /// actually ends with a nul terminator, or if the data contains any interior nul values. |
1170 | | /// |
1171 | | /// # Safety |
1172 | | /// |
1173 | | /// This function is unsafe as there is no guarantee that the given pointer is valid for `len` |
1174 | | /// elements. In addition, no checking for nul values is performed, so if there data does not |
1175 | | /// end with a nul terminator, or if there are any interior nul values, the resulting |
1176 | | /// `U32CString` will be invalid. |
1177 | | /// |
1178 | | /// # Panics |
1179 | | /// |
1180 | | /// Panics if `len` is greater than 0 but `p` is a null pointer. |
1181 | 0 | pub unsafe fn from_char_ptr_with_nul_unchecked(p: *const char, len: usize) -> Self { |
1182 | 0 | UCString::<u32>::from_ptr_with_nul_unchecked(p as *const u32, len) |
1183 | 0 | } |
1184 | | |
1185 | | /// Constructs a `U32CString` from anything that can be converted to an `OsStr`. |
1186 | | /// |
1187 | | /// The string will be scanned for invalid nul values. |
1188 | | /// |
1189 | | /// # Failures |
1190 | | /// |
1191 | | /// This function will return an error if the data contains a nul value. |
1192 | | /// The returned error will contain a `Vec<u16>` as well as the position of the nul value. |
1193 | | /// |
1194 | | /// # Examples |
1195 | | /// |
1196 | | /// ```rust |
1197 | | /// use widestring::U32CString; |
1198 | | /// let s = "MyString"; |
1199 | | /// // Create a wide string from the string |
1200 | | /// let wcstr = U32CString::from_os_str(s).unwrap(); |
1201 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
1202 | | /// ``` |
1203 | | /// |
1204 | | /// The following example demonstrates errors from nul values in a vector. |
1205 | | /// |
1206 | | /// ```rust |
1207 | | /// use widestring::U32CString; |
1208 | | /// let s = "My\u{0}String"; |
1209 | | /// // Create a wide string from the string |
1210 | | /// let res = U32CString::from_os_str(s); |
1211 | | /// assert!(res.is_err()); |
1212 | | /// assert_eq!(res.err().unwrap().nul_position(), 2); |
1213 | | /// ``` |
1214 | | #[cfg(feature = "std")] |
1215 | 0 | pub fn from_os_str(s: impl AsRef<std::ffi::OsStr>) -> Result<Self, NulError<u32>> { |
1216 | 0 | let v: Vec<char> = s.as_ref().to_string_lossy().chars().collect(); |
1217 | 0 | UCString::from_chars(v) |
1218 | 0 | } |
1219 | | |
1220 | | /// Constructs a `U32CString` from anything that can be converted to an `OsStr`, without |
1221 | | /// checking for interior nul values. |
1222 | | /// |
1223 | | /// # Safety |
1224 | | /// |
1225 | | /// This method is equivalent to `from_os_str` except that no runtime assertion is made that |
1226 | | /// `s` contains no nul values. Providing a string with nul values will result in an invalid |
1227 | | /// `U32CString`. |
1228 | | /// |
1229 | | /// # Examples |
1230 | | /// |
1231 | | /// ```rust |
1232 | | /// use widestring::U32CString; |
1233 | | /// let s = "MyString"; |
1234 | | /// // Create a wide string from the string |
1235 | | /// let wcstr = unsafe { U32CString::from_os_str_unchecked(s) }; |
1236 | | /// # assert_eq!(wcstr.to_string_lossy(), s); |
1237 | | /// ``` |
1238 | | #[cfg(feature = "std")] |
1239 | 0 | pub unsafe fn from_os_str_unchecked(s: impl AsRef<std::ffi::OsStr>) -> Self { |
1240 | 0 | let v: Vec<char> = s.as_ref().to_string_lossy().chars().collect(); |
1241 | 0 | UCString::from_chars_unchecked(v) |
1242 | 0 | } |
1243 | | |
1244 | | /// Constructs a `U32CString` from anything that can be converted to an `OsStr` with a nul |
1245 | | /// terminator. |
1246 | | /// |
1247 | | /// The string will be truncated at the first nul value in the string. |
1248 | | /// |
1249 | | /// # Failures |
1250 | | /// |
1251 | | /// This function will return an error if the data does not contain a nul to terminate the |
1252 | | /// string. The returned error will contain the consumed `Vec<u16>`. |
1253 | | /// |
1254 | | /// # Examples |
1255 | | /// |
1256 | | /// ```rust |
1257 | | /// use widestring::U32CString; |
1258 | | /// let s = "My\u{0}String"; |
1259 | | /// // Create a wide string from the string |
1260 | | /// let wcstr = U32CString::from_os_str_with_nul(s).unwrap(); |
1261 | | /// assert_eq!(wcstr.to_string_lossy(), "My"); |
1262 | | /// ``` |
1263 | | /// |
1264 | | /// The following example demonstrates errors from missing nul values in a vector. |
1265 | | /// |
1266 | | /// ```rust |
1267 | | /// use widestring::U32CString; |
1268 | | /// let s = "MyString"; |
1269 | | /// // Create a wide string from the string |
1270 | | /// let res = U32CString::from_os_str_with_nul(s); |
1271 | | /// assert!(res.is_err()); |
1272 | | /// ``` |
1273 | | #[cfg(feature = "std")] |
1274 | 0 | pub fn from_os_str_with_nul( |
1275 | 0 | s: impl AsRef<std::ffi::OsStr>, |
1276 | 0 | ) -> Result<Self, MissingNulError<u32>> { |
1277 | 0 | let v: Vec<char> = s.as_ref().to_string_lossy().chars().collect(); |
1278 | 0 | UCString::from_chars_with_nul(v) |
1279 | 0 | } |
1280 | | |
1281 | | /// Constructs a `U32CString` from anything that can be converted to an `OsStr` that should |
1282 | | /// have a terminating nul, but without checking for any nul values. |
1283 | | /// |
1284 | | /// # Safety |
1285 | | /// |
1286 | | /// This method is equivalent to `from_os_str_with_nul` except that no runtime assertion is |
1287 | | /// made that `s` contains no nul values. Providing a vector with interior nul values or |
1288 | | /// without a terminating nul value will result in an invalid `U32CString`. |
1289 | | /// |
1290 | | /// # Examples |
1291 | | /// |
1292 | | /// ```rust |
1293 | | /// use widestring::U32CString; |
1294 | | /// let s = "My String\u{0}"; |
1295 | | /// // Create a wide string from the string |
1296 | | /// let wcstr = unsafe { U32CString::from_os_str_with_nul_unchecked(s) }; |
1297 | | /// assert_eq!(wcstr.to_string_lossy(), "My String"); |
1298 | | /// ``` |
1299 | | #[cfg(feature = "std")] |
1300 | 0 | pub unsafe fn from_os_str_with_nul_unchecked(s: impl AsRef<std::ffi::OsStr>) -> Self { |
1301 | 0 | let v: Vec<char> = s.as_ref().to_string_lossy().chars().collect(); |
1302 | 0 | UCString::from_chars_with_nul_unchecked(v) |
1303 | 0 | } |
1304 | | } |
1305 | | |
1306 | | impl<C: UChar> Into<Vec<C>> for UCString<C> { |
1307 | 0 | fn into(self) -> Vec<C> { |
1308 | 0 | self.into_vec() |
1309 | 0 | } |
1310 | | } |
1311 | | |
1312 | | impl<'a> From<UCString<u16>> for Cow<'a, UCStr<u16>> { |
1313 | 0 | fn from(s: UCString<u16>) -> Cow<'a, UCStr<u16>> { |
1314 | 0 | Cow::Owned(s) |
1315 | 0 | } |
1316 | | } |
1317 | | |
1318 | | impl<'a> From<UCString<u32>> for Cow<'a, UCStr<u32>> { |
1319 | 0 | fn from(s: UCString<u32>) -> Cow<'a, UCStr<u32>> { |
1320 | 0 | Cow::Owned(s) |
1321 | 0 | } |
1322 | | } |
1323 | | |
1324 | | #[cfg(feature = "std")] |
1325 | | impl From<UCString<u16>> for std::ffi::OsString { |
1326 | 0 | fn from(s: UCString<u16>) -> std::ffi::OsString { |
1327 | 0 | s.to_os_string() |
1328 | 0 | } |
1329 | | } |
1330 | | |
1331 | | #[cfg(feature = "std")] |
1332 | | impl From<UCString<u32>> for std::ffi::OsString { |
1333 | 0 | fn from(s: UCString<u32>) -> std::ffi::OsString { |
1334 | 0 | s.to_os_string() |
1335 | 0 | } |
1336 | | } |
1337 | | |
1338 | | impl<C: UChar> From<UCString<C>> for UString<C> { |
1339 | 0 | fn from(s: UCString<C>) -> Self { |
1340 | 0 | s.to_ustring() |
1341 | 0 | } |
1342 | | } |
1343 | | |
1344 | | impl<'a, C: UChar, T: ?Sized + AsRef<UCStr<C>>> From<&'a T> for UCString<C> { |
1345 | 0 | fn from(s: &'a T) -> Self { |
1346 | 0 | s.as_ref().to_ucstring() |
1347 | 0 | } |
1348 | | } |
1349 | | |
1350 | | impl<C: UChar> Index<RangeFull> for UCString<C> { |
1351 | | type Output = UCStr<C>; |
1352 | | |
1353 | | #[inline] |
1354 | 58.9k | fn index(&self, _index: RangeFull) -> &UCStr<C> { |
1355 | 58.9k | UCStr::from_inner(&self.inner) |
1356 | 58.9k | } <widestring::ucstring::UCString<u16> as core::ops::index::Index<core::ops::range::RangeFull>>::index Line | Count | Source | 1354 | 29.9k | fn index(&self, _index: RangeFull) -> &UCStr<C> { | 1355 | 29.9k | UCStr::from_inner(&self.inner) | 1356 | 29.9k | } |
Unexecuted instantiation: <widestring::ucstring::UCString<u32> as core::ops::index::Index<core::ops::range::RangeFull>>::index Unexecuted instantiation: <widestring::ucstring::UCString<u16> as core::ops::index::Index<core::ops::range::RangeFull>>::index <widestring::ucstring::UCString<u16> as core::ops::index::Index<core::ops::range::RangeFull>>::index Line | Count | Source | 1354 | 28.9k | fn index(&self, _index: RangeFull) -> &UCStr<C> { | 1355 | 28.9k | UCStr::from_inner(&self.inner) | 1356 | 28.9k | } |
|
1357 | | } |
1358 | | |
1359 | | impl<C: UChar> Deref for UCString<C> { |
1360 | | type Target = UCStr<C>; |
1361 | | |
1362 | | #[inline] |
1363 | 58.9k | fn deref(&self) -> &UCStr<C> { |
1364 | 58.9k | &self[..] |
1365 | 58.9k | } <widestring::ucstring::UCString<u16> as core::ops::deref::Deref>::deref Line | Count | Source | 1363 | 29.9k | fn deref(&self) -> &UCStr<C> { | 1364 | 29.9k | &self[..] | 1365 | 29.9k | } |
Unexecuted instantiation: <widestring::ucstring::UCString<u32> as core::ops::deref::Deref>::deref Unexecuted instantiation: <widestring::ucstring::UCString<u16> as core::ops::deref::Deref>::deref <widestring::ucstring::UCString<u16> as core::ops::deref::Deref>::deref Line | Count | Source | 1363 | 28.9k | fn deref(&self) -> &UCStr<C> { | 1364 | 28.9k | &self[..] | 1365 | 28.9k | } |
|
1366 | | } |
1367 | | |
1368 | | impl<'a> Default for &'a UCStr<u16> { |
1369 | 0 | fn default() -> Self { |
1370 | | const SLICE: &[u16] = &[UChar::NUL]; |
1371 | 0 | unsafe { UCStr::from_slice_with_nul_unchecked(SLICE) } |
1372 | 0 | } |
1373 | | } |
1374 | | |
1375 | | impl<'a> Default for &'a UCStr<u32> { |
1376 | 0 | fn default() -> Self { |
1377 | | const SLICE: &[u32] = &[UChar::NUL]; |
1378 | 0 | unsafe { UCStr::from_slice_with_nul_unchecked(SLICE) } |
1379 | 0 | } |
1380 | | } |
1381 | | |
1382 | | impl Default for UCString<u16> { |
1383 | 0 | fn default() -> Self { |
1384 | 0 | let def: &UCStr<u16> = Default::default(); |
1385 | 0 | def.to_ucstring() |
1386 | 0 | } |
1387 | | } |
1388 | | |
1389 | | impl Default for UCString<u32> { |
1390 | 0 | fn default() -> Self { |
1391 | 0 | let def: &UCStr<u32> = Default::default(); |
1392 | 0 | def.to_ucstring() |
1393 | 0 | } |
1394 | | } |
1395 | | |
1396 | | // Turns this `U16CString` into an empty string to prevent |
1397 | | // memory unsafe code from working by accident. Inline |
1398 | | // to prevent LLVM from optimizing it away in debug builds. |
1399 | | impl<C: UChar> Drop for UCString<C> { |
1400 | | #[inline] |
1401 | 58.9k | fn drop(&mut self) { |
1402 | 58.9k | unsafe { |
1403 | 58.9k | *self.inner.get_unchecked_mut(0) = UChar::NUL; |
1404 | 58.9k | } |
1405 | 58.9k | } <widestring::ucstring::UCString<u16> as core::ops::drop::Drop>::drop Line | Count | Source | 1401 | 29.9k | fn drop(&mut self) { | 1402 | 29.9k | unsafe { | 1403 | 29.9k | *self.inner.get_unchecked_mut(0) = UChar::NUL; | 1404 | 29.9k | } | 1405 | 29.9k | } |
Unexecuted instantiation: <widestring::ucstring::UCString<u32> as core::ops::drop::Drop>::drop Unexecuted instantiation: <widestring::ucstring::UCString<u16> as core::ops::drop::Drop>::drop <widestring::ucstring::UCString<u16> as core::ops::drop::Drop>::drop Line | Count | Source | 1401 | 28.9k | fn drop(&mut self) { | 1402 | 28.9k | unsafe { | 1403 | 28.9k | *self.inner.get_unchecked_mut(0) = UChar::NUL; | 1404 | 28.9k | } | 1405 | 28.9k | } |
|
1406 | | } |
1407 | | |
1408 | | impl<C: UChar> Borrow<UCStr<C>> for UCString<C> { |
1409 | 0 | fn borrow(&self) -> &UCStr<C> { |
1410 | 0 | &self[..] |
1411 | 0 | } |
1412 | | } |
1413 | | |
1414 | | impl<C: UChar> ToOwned for UCStr<C> { |
1415 | | type Owned = UCString<C>; |
1416 | 0 | fn to_owned(&self) -> UCString<C> { |
1417 | 0 | self.to_ucstring() |
1418 | 0 | } |
1419 | | } |
1420 | | |
1421 | | impl<'a> From<&'a UCStr<u16>> for Cow<'a, UCStr<u16>> { |
1422 | 0 | fn from(s: &'a UCStr<u16>) -> Cow<'a, UCStr<u16>> { |
1423 | 0 | Cow::Borrowed(s) |
1424 | 0 | } |
1425 | | } |
1426 | | |
1427 | | impl<'a> From<&'a UCStr<u32>> for Cow<'a, UCStr<u32>> { |
1428 | 0 | fn from(s: &'a UCStr<u32>) -> Cow<'a, UCStr<u32>> { |
1429 | 0 | Cow::Borrowed(s) |
1430 | 0 | } |
1431 | | } |
1432 | | |
1433 | | impl<C: UChar> AsRef<UCStr<C>> for UCStr<C> { |
1434 | 0 | fn as_ref(&self) -> &Self { |
1435 | 0 | self |
1436 | 0 | } |
1437 | | } |
1438 | | |
1439 | | impl<C: UChar> AsRef<UCStr<C>> for UCString<C> { |
1440 | 0 | fn as_ref(&self) -> &UCStr<C> { |
1441 | 0 | self |
1442 | 0 | } |
1443 | | } |
1444 | | |
1445 | | impl<C: UChar> AsRef<[C]> for UCStr<C> { |
1446 | 0 | fn as_ref(&self) -> &[C] { |
1447 | 0 | self.as_slice() |
1448 | 0 | } |
1449 | | } |
1450 | | |
1451 | | impl<C: UChar> AsRef<[C]> for UCString<C> { |
1452 | 0 | fn as_ref(&self) -> &[C] { |
1453 | 0 | self.as_slice() |
1454 | 0 | } |
1455 | | } |
1456 | | |
1457 | | impl<'a, C: UChar> From<&'a UCStr<C>> for Box<UCStr<C>> { |
1458 | 0 | fn from(s: &'a UCStr<C>) -> Box<UCStr<C>> { |
1459 | 0 | let boxed: Box<[C]> = Box::from(s.as_slice_with_nul()); |
1460 | 0 | unsafe { Box::from_raw(Box::into_raw(boxed) as *mut UCStr<C>) } |
1461 | 0 | } |
1462 | | } |
1463 | | |
1464 | | impl<C: UChar> From<Box<UCStr<C>>> for UCString<C> { |
1465 | | #[inline] |
1466 | 0 | fn from(s: Box<UCStr<C>>) -> Self { |
1467 | 0 | s.into_ucstring() |
1468 | 0 | } |
1469 | | } |
1470 | | |
1471 | | impl<C: UChar> From<UCString<C>> for Box<UCStr<C>> { |
1472 | | #[inline] |
1473 | 0 | fn from(s: UCString<C>) -> Box<UCStr<C>> { |
1474 | 0 | s.into_boxed_ucstr() |
1475 | 0 | } |
1476 | | } |
1477 | | |
1478 | | impl<C: UChar> Default for Box<UCStr<C>> { |
1479 | 0 | fn default() -> Box<UCStr<C>> { |
1480 | 0 | let boxed: Box<[C]> = Box::from([UChar::NUL]); |
1481 | 0 | unsafe { Box::from_raw(Box::into_raw(boxed) as *mut UCStr<C>) } |
1482 | 0 | } |
1483 | | } |
1484 | | |
1485 | | impl<C: UChar> NulError<C> { |
1486 | | /// Returns the position of the nul value in the slice that was provided to `U16CString`. |
1487 | 0 | pub fn nul_position(&self) -> usize { |
1488 | 0 | self.0 |
1489 | 0 | } |
1490 | | |
1491 | | /// Consumes this error, returning the underlying vector of u16 values which generated the error |
1492 | | /// in the first place. |
1493 | 0 | pub fn into_vec(self) -> Vec<C> { |
1494 | 0 | self.1 |
1495 | 0 | } |
1496 | | } |
1497 | | |
1498 | | impl<C: UChar> Into<Vec<C>> for NulError<C> { |
1499 | 0 | fn into(self) -> Vec<C> { |
1500 | 0 | self.into_vec() |
1501 | 0 | } |
1502 | | } |
1503 | | |
1504 | | impl<C: UChar> core::fmt::Display for NulError<C> { |
1505 | 0 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { |
1506 | 0 | write!(f, "nul value found at position {}", self.0) |
1507 | 0 | } Unexecuted instantiation: <widestring::ucstring::NulError<u16> as core::fmt::Display>::fmt Unexecuted instantiation: <widestring::ucstring::NulError<u16> as core::fmt::Display>::fmt Unexecuted instantiation: <widestring::ucstring::NulError<_> as core::fmt::Display>::fmt |
1508 | | } |
1509 | | |
1510 | | #[cfg(feature = "std")] |
1511 | | impl<C: UChar> std::error::Error for NulError<C> { |
1512 | 0 | fn description(&self) -> &str { |
1513 | 0 | "nul value found" |
1514 | 0 | } Unexecuted instantiation: <widestring::ucstring::NulError<u16> as core::error::Error>::description Unexecuted instantiation: <widestring::ucstring::NulError<u16> as core::error::Error>::description Unexecuted instantiation: <widestring::ucstring::NulError<_> as core::error::Error>::description |
1515 | | } |
1516 | | |
1517 | | /// An owned, mutable C-style "wide" string for FFI that is nul-aware and nul-terminated. |
1518 | | /// |
1519 | | /// `U16CString` is aware of nul values. Unless unchecked conversions are used, all `U16CString` |
1520 | | /// strings end with a nul-terminator in the underlying buffer and contain no internal nul values. |
1521 | | /// The strings may still contain invalid or ill-formed UTF-16 data. These strings are intended to |
1522 | | /// be used with FFI functions such as Windows API that may require nul-terminated strings. |
1523 | | /// |
1524 | | /// `U16CString` can be converted to and from many other string types, including `U16String`, |
1525 | | /// `OsString`, and `String`, making proper Unicode FFI safe and easy. |
1526 | | /// |
1527 | | /// # Examples |
1528 | | /// |
1529 | | /// The following example constructs a `U16CString` and shows how to convert a `U16CString` to a |
1530 | | /// regular Rust `String`. |
1531 | | /// |
1532 | | /// ```rust |
1533 | | /// use widestring::U16CString; |
1534 | | /// let s = "Test"; |
1535 | | /// // Create a wide string from the rust string |
1536 | | /// let wstr = U16CString::from_str(s).unwrap(); |
1537 | | /// // Convert back to a rust string |
1538 | | /// let rust_str = wstr.to_string_lossy(); |
1539 | | /// assert_eq!(rust_str, "Test"); |
1540 | | /// ``` |
1541 | | pub type U16CString = UCString<u16>; |
1542 | | |
1543 | | /// An owned, mutable C-style wide string for FFI that is nul-aware and nul-terminated. |
1544 | | /// |
1545 | | /// `U32CString` is aware of nul values. Unless unchecked conversions are used, all `U32CString` |
1546 | | /// strings end with a nul-terminator in the underlying buffer and contain no internal nul values. |
1547 | | /// The strings may still contain invalid or ill-formed UTF-32 data. These strings are intended to |
1548 | | /// be used with FFI functions such as Windows API that may require nul-terminated strings. |
1549 | | /// |
1550 | | /// `U32CString` can be converted to and from many other string types, including `U32String`, |
1551 | | /// `OsString`, and `String`, making proper Unicode FFI safe and easy. |
1552 | | /// |
1553 | | /// # Examples |
1554 | | /// |
1555 | | /// The following example constructs a `U32CString` and shows how to convert a `U32CString` to a |
1556 | | /// regular Rust `String`. |
1557 | | /// |
1558 | | /// ```rust |
1559 | | /// use widestring::U32CString; |
1560 | | /// let s = "Test"; |
1561 | | /// // Create a wide string from the rust string |
1562 | | /// let wstr = U32CString::from_str(s).unwrap(); |
1563 | | /// // Convert back to a rust string |
1564 | | /// let rust_str = wstr.to_string_lossy(); |
1565 | | /// assert_eq!(rust_str, "Test"); |
1566 | | /// ``` |
1567 | | pub type U32CString = UCString<u32>; |
1568 | | |
1569 | | /// Alias for `U16String` or `U32String` depending on platform. Intended to match typical C `wchar_t` size on platform. |
1570 | | pub type WideCString = UCString<WideChar>; |