Coverage Report

Created: 2026-08-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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>;