widestring/
ustring.rs

1//! Owned, growable wide strings with undefined encoding.
2//!
3//! This module contains wide strings and related types.
4
5use crate::{U16CStr, U16CString, U16Str, U32CStr, U32CString, U32Str};
6#[allow(unused_imports)]
7use alloc::{
8    borrow::{Cow, ToOwned},
9    boxed::Box,
10    string::String,
11    vec::Vec,
12};
13#[allow(unused_imports)]
14use core::{
15    borrow::{Borrow, BorrowMut},
16    char, cmp,
17    convert::Infallible,
18    fmt::Write,
19    iter::FromIterator,
20    mem,
21    ops::{Add, AddAssign, Deref, DerefMut, Index, IndexMut, RangeBounds},
22    slice::{self, SliceIndex},
23    str::FromStr,
24};
25
26mod iter;
27
28pub use iter::*;
29
30macro_rules! ustring_common_impl {
31    {
32        $(#[$ustring_meta:meta])*
33        struct $ustring:ident([$uchar:ty]);
34        type UStr = $ustr:ident;
35        type UCString = $ucstring:ident;
36        type UCStr = $ucstr:ident;
37        type UtfStr = $utfstr:ident;
38        type UtfString = $utfstring:ident;
39        $(#[$push_meta:meta])*
40        fn push() -> {}
41        $(#[$push_slice_meta:meta])*
42        fn push_slice() -> {}
43        $(#[$into_boxed_ustr_meta:meta])*
44        fn into_boxed_ustr() -> {}
45    } => {
46        $(#[$ustring_meta])*
47        #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
48        #[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
49        pub struct $ustring {
50            pub(crate) inner: Vec<$uchar>,
51        }
52
53        impl $ustring {
54            /// Constructs a new empty wide string.
55            #[inline]
56            #[must_use]
57            pub const fn new() -> Self {
58                Self { inner: Vec::new() }
59            }
60
61            /// Constructs a wide string from a vector.
62            ///
63            /// No checks are made on the contents of the vector. It may or may not be valid
64            /// character data.
65            ///
66            /// # Examples
67            ///
68            /// ```rust
69            /// use widestring::U16String;
70            /// let v = vec![84u16, 104u16, 101u16]; // 'T' 'h' 'e'
71            /// # let cloned = v.clone();
72            /// // Create a wide string from the vector
73            /// let wstr = U16String::from_vec(v);
74            /// # assert_eq!(wstr.into_vec(), cloned);
75            /// ```
76            ///
77            /// ```rust
78            /// use widestring::U32String;
79            /// let v = vec![84u32, 104u32, 101u32]; // 'T' 'h' 'e'
80            /// # let cloned = v.clone();
81            /// // Create a wide string from the vector
82            /// let wstr = U32String::from_vec(v);
83            /// # assert_eq!(wstr.into_vec(), cloned);
84            /// ```
85            #[inline]
86            #[must_use]
87            pub fn from_vec(raw: impl Into<Vec<$uchar>>) -> Self {
88                Self { inner: raw.into() }
89            }
90
91            /// Constructs a wide string copy from a pointer and a length.
92            ///
93            /// The `len` argument is the number of elements, **not** the number of bytes.
94            ///
95            /// # Safety
96            ///
97            /// This function is unsafe as there is no guarantee that the given pointer is valid for
98            /// `len` elements.
99            ///
100            /// In addition, the data must meet the safety conditions of
101            /// [std::slice::from_raw_parts].
102            ///
103            /// # Panics
104            ///
105            /// Panics if `len` is greater than 0 but `p` is a null pointer.
106            #[must_use]
107            pub unsafe fn from_ptr(p: *const $uchar, len: usize) -> Self {
108                if len == 0 {
109                    return Self::new();
110                }
111                assert!(!p.is_null());
112                let slice = slice::from_raw_parts(p, len);
113                Self::from_vec(slice)
114            }
115
116            /// Constructs a wide string with the given capacity.
117            ///
118            /// The string will be able to hold exactly `capacity` elements without reallocating.
119            /// If `capacity` is set to 0, the string will not initially allocate.
120            #[inline]
121            #[must_use]
122            pub fn with_capacity(capacity: usize) -> Self {
123                Self {
124                    inner: Vec::with_capacity(capacity),
125                }
126            }
127
128            /// Returns the capacity this wide string can hold without reallocating.
129            #[inline]
130            #[must_use]
131            pub fn capacity(&self) -> usize {
132                self.inner.capacity()
133            }
134
135            /// Truncates the wide string to zero length.
136            #[inline]
137            pub fn clear(&mut self) {
138                self.inner.clear()
139            }
140
141            /// Reserves the capacity for at least `additional` more capacity to be inserted in the
142            /// given wide string.
143            ///
144            /// More space may be reserved to avoid frequent allocations.
145            #[inline]
146            pub fn reserve(&mut self, additional: usize) {
147                self.inner.reserve(additional)
148            }
149
150            /// Reserves the minimum capacity for exactly `additional` more capacity to be inserted
151            /// in the given wide string. Does nothing if the capacity is already sufficient.
152            ///
153            /// Note that the allocator may give more space than is requested. Therefore capacity
154            /// can not be relied upon to be precisely minimal. Prefer [`reserve`][Self::reserve] if
155            /// future insertions are expected.
156            #[inline]
157            pub fn reserve_exact(&mut self, additional: usize) {
158                self.inner.reserve_exact(additional)
159            }
160
161            /// Converts the string into a [`Vec`], consuming the string in the process.
162            #[inline]
163            #[must_use]
164            pub fn into_vec(self) -> Vec<$uchar> {
165                self.inner
166            }
167
168            /// Converts to a wide string slice.
169            #[inline]
170            #[must_use]
171            pub fn as_ustr(&self) -> &$ustr {
172                $ustr::from_slice(&self.inner)
173            }
174
175            /// Converts to a mutable wide string slice.
176            #[inline]
177            #[must_use]
178            pub fn as_mut_ustr(&mut self) -> &mut $ustr {
179                $ustr::from_slice_mut(&mut self.inner)
180            }
181
182            /// Returns a [`Vec`] reference to the contents of this string.
183            #[inline]
184            #[must_use]
185            pub fn as_vec(&self) -> &Vec<$uchar> {
186                &self.inner
187            }
188
189            /// Returns a mutable reference to the contents of this string.
190            #[inline]
191            #[must_use]
192            pub fn as_mut_vec(&mut self) -> &mut Vec<$uchar> {
193                &mut self.inner
194            }
195
196            $(#[$push_meta])*
197            #[inline]
198            pub fn push(&mut self, s: impl AsRef<$ustr>) {
199                self.inner.extend_from_slice(&s.as_ref().as_slice())
200            }
201
202            $(#[$push_slice_meta])*
203            #[inline]
204            pub fn push_slice(&mut self, s: impl AsRef<[$uchar]>) {
205                self.inner.extend_from_slice(s.as_ref())
206            }
207
208            /// Shrinks the capacity of the wide string to match its length.
209            #[inline]
210            pub fn shrink_to_fit(&mut self) {
211                self.inner.shrink_to_fit();
212            }
213
214            /// Shrinks the capacity of this string with a lower bound.
215            ///
216            /// The capacity will remain at least as large as both the length and the supplied
217            /// value.
218            ///
219            /// If the current capacity is less than the lower limit, this is a no-op.
220            #[inline]
221            pub fn shrink_to(&mut self, min_capacity: usize) {
222                self.inner.shrink_to(min_capacity)
223            }
224
225            $(#[$into_boxed_ustr_meta])*
226            #[must_use]
227            pub fn into_boxed_ustr(self) -> Box<$ustr> {
228                let rw = Box::into_raw(self.inner.into_boxed_slice()) as *mut $ustr;
229                unsafe { Box::from_raw(rw) }
230            }
231
232            /// Shortens this string to the specified length.
233            ///
234            /// If `new_len` is greater than the string's current length, this has no effect.
235            ///
236            /// Note that this method has no effect on the allocated capacity of the string.
237            #[inline]
238            pub fn truncate(&mut self, new_len: usize) {
239                self.inner.truncate(new_len)
240            }
241
242            /// Inserts a string slice into this string at a specified position.
243            ///
244            /// This is an _O(n)_ operation as it requires copying every element in the buffer.
245            ///
246            /// # Panics
247            ///
248            /// Panics if `idx` is larger than the string's length.
249            pub fn insert_ustr(&mut self, idx: usize, string: &$ustr) {
250                assert!(idx <= self.len());
251                self.inner
252                    .resize_with(self.len() + string.len(), Default::default);
253                self.inner.copy_within(idx.., idx + string.len());
254                self.inner[idx..].copy_from_slice(string.as_slice());
255            }
256
257            /// Splits the string into two at the given index.
258            ///
259            /// Returns a newly allocated string. `self` contains values `[0, at)`, and the returned
260            /// string contains values `[at, len)`.
261            ///
262            /// Note that the capacity of `self` does not change.
263            ///
264            /// # Panics
265            ///
266            /// Panics if `at` is equal to or greater than the length of the string.
267            #[inline]
268            #[must_use]
269            pub fn split_off(&mut self, at: usize) -> $ustring {
270                Self::from_vec(self.inner.split_off(at))
271            }
272
273            /// Retains only the elements specified by the predicate.
274            ///
275            /// In other words, remove all elements `e` such that `f(e)` returns `false`. This
276            /// method operates in place, visiting each element exactly once in the original order,
277            /// and preserves the order of the retained elements.
278            pub fn retain<F>(&mut self, mut f: F)
279            where
280                F: FnMut($uchar) -> bool,
281            {
282                self.inner.retain(|e| f(*e))
283            }
284
285            /// Creates a draining iterator that removes the specified range in the string and
286            /// yields the removed elements.
287            ///
288            /// Note: The element range is removed even if the iterator is not consumed until the
289            /// end.
290            ///
291            /// # Panics
292            ///
293            /// Panics if the starting point or end point are out of bounds.
294            pub fn drain<R>(&mut self, range: R) -> Drain<'_, $uchar>
295            where
296                R: RangeBounds<usize>,
297            {
298                Drain { inner: self.inner.drain(range) }
299            }
300
301            /// Removes the specified range in the string, and replaces it with the given string.
302            ///
303            /// The given string doesn't need to be the same length as the range.
304            ///
305            /// # Panics
306            ///
307            /// Panics if the starting point or end point are out of bounds.
308            pub fn replace_range<R>(&mut self, range: R, replace_with: impl AsRef<$ustr>)
309            where
310                R: RangeBounds<usize>,
311            {
312                self.inner
313                    .splice(range, replace_with.as_ref().as_slice().iter().copied());
314            }
315        }
316
317        impl Add<&$ustr> for $ustring {
318            type Output = $ustring;
319
320            #[inline]
321            fn add(mut self, rhs: &$ustr) -> Self::Output {
322                self.push(rhs);
323                self
324            }
325        }
326
327        impl Add<&$ucstr> for $ustring {
328            type Output = $ustring;
329
330            #[inline]
331            fn add(mut self, rhs: &$ucstr) -> Self::Output {
332                self.push(rhs);
333                self
334            }
335        }
336
337        impl Add<&crate::$utfstr> for $ustring {
338            type Output = $ustring;
339
340            #[inline]
341            fn add(mut self, rhs: &crate::$utfstr) -> Self::Output {
342                self.push(rhs);
343                self
344            }
345        }
346
347        impl Add<&str> for $ustring {
348            type Output = $ustring;
349
350            #[inline]
351            fn add(mut self, rhs: &str) -> Self::Output {
352                self.push_str(rhs);
353                self
354            }
355        }
356
357        impl AddAssign<&$ustr> for $ustring {
358            #[inline]
359            fn add_assign(&mut self, rhs: &$ustr) {
360                self.push(rhs)
361            }
362        }
363
364        impl AddAssign<&$ucstr> for $ustring {
365            #[inline]
366            fn add_assign(&mut self, rhs: &$ucstr) {
367                self.push(rhs)
368            }
369        }
370
371        impl AddAssign<&crate::$utfstr> for $ustring {
372            #[inline]
373            fn add_assign(&mut self, rhs: &crate::$utfstr) {
374                self.push(rhs)
375            }
376        }
377
378        impl AddAssign<&str> for $ustring {
379            #[inline]
380            fn add_assign(&mut self, rhs: &str) {
381                self.push_str(rhs);
382            }
383        }
384
385        impl AsMut<$ustr> for $ustring {
386            #[inline]
387            fn as_mut(&mut self) -> &mut $ustr {
388                self.as_mut_ustr()
389            }
390        }
391
392        impl AsMut<[$uchar]> for $ustring {
393            #[inline]
394            fn as_mut(&mut self) -> &mut [$uchar] {
395                self.as_mut_slice()
396            }
397        }
398
399        impl AsRef<$ustr> for $ustring {
400            #[inline]
401            fn as_ref(&self) -> &$ustr {
402                self.as_ustr()
403            }
404        }
405
406        impl AsRef<[$uchar]> for $ustring {
407            #[inline]
408            fn as_ref(&self) -> &[$uchar] {
409                self.as_slice()
410            }
411        }
412
413        impl Borrow<$ustr> for $ustring {
414            #[inline]
415            fn borrow(&self) -> &$ustr {
416                self.as_ustr()
417            }
418        }
419
420        impl BorrowMut<$ustr> for $ustring {
421            #[inline]
422            fn borrow_mut(&mut self) -> &mut $ustr {
423                self.as_mut_ustr()
424            }
425        }
426
427        impl Default for Box<$ustr> {
428            #[inline]
429            fn default() -> Self {
430                let boxed: Box<[$uchar]> = Box::from([]);
431                let rw = Box::into_raw(boxed) as *mut $ustr;
432                unsafe { Box::from_raw(rw) }
433            }
434        }
435
436        impl Deref for $ustring {
437            type Target = $ustr;
438
439            #[inline]
440            fn deref(&self) -> &$ustr {
441                self.as_ustr()
442            }
443        }
444
445        impl DerefMut for $ustring {
446            #[inline]
447            fn deref_mut(&mut self) -> &mut Self::Target {
448                self.as_mut_ustr()
449            }
450        }
451
452        impl<'a> Extend<&'a $ustr> for $ustring {
453            #[inline]
454            fn extend<T: IntoIterator<Item = &'a $ustr>>(&mut self, iter: T) {
455                iter.into_iter().for_each(|s| self.push(s))
456            }
457        }
458
459        impl<'a> Extend<&'a $ucstr> for $ustring {
460            #[inline]
461            fn extend<T: IntoIterator<Item = &'a $ucstr>>(&mut self, iter: T) {
462                iter.into_iter().for_each(|s| self.push(s))
463            }
464        }
465
466        impl<'a> Extend<&'a crate::$utfstr> for $ustring {
467            #[inline]
468            fn extend<T: IntoIterator<Item = &'a crate::$utfstr>>(&mut self, iter: T) {
469                iter.into_iter().for_each(|s| self.push(s))
470            }
471        }
472
473        impl<'a> Extend<&'a str> for $ustring {
474            #[inline]
475            fn extend<T: IntoIterator<Item = &'a str>>(&mut self, iter: T) {
476                iter.into_iter().for_each(|s| self.push_str(s))
477            }
478        }
479
480        impl Extend<$ustring> for $ustring {
481            #[inline]
482            fn extend<T: IntoIterator<Item = $ustring>>(&mut self, iter: T) {
483                iter.into_iter().for_each(|s| self.push(s))
484            }
485        }
486
487        impl Extend<$ucstring> for $ustring {
488            #[inline]
489            fn extend<T: IntoIterator<Item = $ucstring>>(&mut self, iter: T) {
490                iter.into_iter().for_each(|s| self.push(s.as_ucstr()))
491            }
492        }
493
494        impl Extend<crate::$utfstring> for $ustring {
495            #[inline]
496            fn extend<T: IntoIterator<Item = crate::$utfstring>>(&mut self, iter: T) {
497                iter.into_iter().for_each(|s| self.push(s.as_ustr()))
498            }
499        }
500
501        impl Extend<String> for $ustring {
502            #[inline]
503            fn extend<T: IntoIterator<Item = String>>(&mut self, iter: T) {
504                iter.into_iter().for_each(|s| self.push_str(s))
505            }
506        }
507
508        impl Extend<char> for $ustring {
509            #[inline]
510            fn extend<T: IntoIterator<Item = char>>(&mut self, iter: T) {
511                let iter = iter.into_iter();
512                let (lower_bound, _) = iter.size_hint();
513                self.reserve(lower_bound);
514                iter.for_each(|c| self.push_char(c));
515            }
516        }
517
518        impl<'a> Extend<&'a char> for $ustring {
519            #[inline]
520            fn extend<T: IntoIterator<Item = &'a char>>(&mut self, iter: T) {
521                self.extend(iter.into_iter().copied())
522            }
523        }
524
525        impl Extend<Box<$ustr>> for $ustring {
526            #[inline]
527            fn extend<T: IntoIterator<Item = Box<$ustr>>>(&mut self, iter: T) {
528                iter.into_iter().for_each(|s| self.push(s))
529            }
530        }
531
532        impl<'a> Extend<Cow<'a, $ustr>> for $ustring {
533            #[inline]
534            fn extend<T: IntoIterator<Item = Cow<'a, $ustr>>>(&mut self, iter: T) {
535                iter.into_iter().for_each(|s| self.push(s))
536            }
537        }
538
539        impl From<$ustring> for Vec<$uchar> {
540            #[inline]
541            fn from(value: $ustring) -> Self {
542                value.into_vec()
543            }
544        }
545
546        impl<'a> From<$ustring> for Cow<'a, $ustr> {
547            #[inline]
548            fn from(s: $ustring) -> Self {
549                Cow::Owned(s)
550            }
551        }
552
553        impl From<Vec<$uchar>> for $ustring {
554            #[inline]
555            fn from(value: Vec<$uchar>) -> Self {
556                Self::from_vec(value)
557            }
558        }
559
560        impl From<String> for $ustring {
561            #[inline]
562            fn from(s: String) -> Self {
563                Self::from_str(&s)
564            }
565        }
566
567        impl From<&str> for $ustring {
568            #[inline]
569            fn from(s: &str) -> Self {
570                Self::from_str(s)
571            }
572        }
573
574        #[cfg(feature = "std")]
575        impl From<std::ffi::OsString> for $ustring {
576            #[inline]
577            fn from(s: std::ffi::OsString) -> Self {
578                Self::from_os_str(&s)
579            }
580        }
581
582        #[cfg(feature = "std")]
583        impl From<$ustring> for std::ffi::OsString {
584            #[inline]
585            fn from(s: $ustring) -> Self {
586                s.to_os_string()
587            }
588        }
589
590        impl<'a, T: ?Sized + AsRef<$ustr>> From<&'a T> for $ustring {
591            #[inline]
592            fn from(s: &'a T) -> Self {
593                s.as_ref().to_ustring()
594            }
595        }
596
597        impl<'a> From<&'a $ustr> for Cow<'a, $ustr> {
598            #[inline]
599            fn from(s: &'a $ustr) -> Self {
600                Cow::Borrowed(s)
601            }
602        }
603
604        impl<'a> From<&'a $ustr> for Box<$ustr> {
605            fn from(s: &'a $ustr) -> Self {
606                let boxed: Box<[$uchar]> = Box::from(&s.inner);
607                let rw = Box::into_raw(boxed) as *mut $ustr;
608                unsafe { Box::from_raw(rw) }
609            }
610        }
611
612        impl From<Box<$ustr>> for $ustring {
613            #[inline]
614            fn from(boxed: Box<$ustr>) -> Self {
615                boxed.into_ustring()
616            }
617        }
618
619        impl From<$ustring> for Box<$ustr> {
620            #[inline]
621            fn from(s: $ustring) -> Self {
622                s.into_boxed_ustr()
623            }
624        }
625
626        impl<'a> FromIterator<&'a $ustr> for $ustring {
627            #[inline]
628            fn from_iter<T: IntoIterator<Item = &'a $ustr>>(iter: T) -> Self {
629                let mut string = Self::new();
630                string.extend(iter);
631                string
632            }
633        }
634
635        impl<'a> FromIterator<&'a $ucstr> for $ustring {
636            #[inline]
637            fn from_iter<T: IntoIterator<Item = &'a $ucstr>>(iter: T) -> Self {
638                let mut string = Self::new();
639                string.extend(iter);
640                string
641            }
642        }
643
644        impl<'a> FromIterator<&'a crate::$utfstr> for $ustring {
645            #[inline]
646            fn from_iter<T: IntoIterator<Item = &'a crate::$utfstr>>(iter: T) -> Self {
647                let mut string = Self::new();
648                string.extend(iter);
649                string
650            }
651        }
652
653        impl<'a> FromIterator<&'a str> for $ustring {
654            #[inline]
655            fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
656                let mut string = Self::new();
657                string.extend(iter);
658                string
659            }
660        }
661
662        impl FromIterator<$ustring> for $ustring {
663            #[inline]
664            fn from_iter<T: IntoIterator<Item = $ustring>>(iter: T) -> Self {
665                let mut string = Self::new();
666                string.extend(iter);
667                string
668            }
669        }
670
671        impl FromIterator<$ucstring> for $ustring {
672            #[inline]
673            fn from_iter<T: IntoIterator<Item = $ucstring>>(iter: T) -> Self {
674                let mut string = Self::new();
675                string.extend(iter);
676                string
677            }
678        }
679
680        impl FromIterator<crate::$utfstring> for $ustring {
681            #[inline]
682            fn from_iter<T: IntoIterator<Item = crate::$utfstring>>(iter: T) -> Self {
683                let mut string = Self::new();
684                string.extend(iter);
685                string
686            }
687        }
688
689        impl FromIterator<String> for $ustring {
690            #[inline]
691            fn from_iter<T: IntoIterator<Item = String>>(iter: T) -> Self {
692                let mut string = Self::new();
693                string.extend(iter);
694                string
695            }
696        }
697
698        impl FromIterator<char> for $ustring {
699            #[inline]
700            fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
701                let mut string = Self::new();
702                string.extend(iter);
703                string
704            }
705        }
706
707        impl<'a> FromIterator<&'a char> for $ustring {
708            #[inline]
709            fn from_iter<T: IntoIterator<Item = &'a char>>(iter: T) -> Self {
710                let mut string = Self::new();
711                string.extend(iter);
712                string
713            }
714        }
715
716        impl FromIterator<Box<$ustr>> for $ustring {
717            #[inline]
718            fn from_iter<T: IntoIterator<Item = Box<$ustr>>>(iter: T) -> Self {
719                let mut string = Self::new();
720                string.extend(iter);
721                string
722            }
723        }
724
725        impl<'a> FromIterator<Cow<'a, $ustr>> for $ustring {
726            #[inline]
727            fn from_iter<T: IntoIterator<Item = Cow<'a, $ustr>>>(iter: T) -> Self {
728                let mut string = Self::new();
729                string.extend(iter);
730                string
731            }
732        }
733
734        impl FromStr for $ustring {
735            type Err = Infallible;
736
737            #[inline]
738            fn from_str(s: &str) -> Result<Self, Self::Err> {
739                Ok(Self::from_str(s))
740            }
741        }
742
743        impl<I> Index<I> for $ustring
744        where
745            I: SliceIndex<[$uchar], Output = [$uchar]>,
746        {
747            type Output = $ustr;
748
749            #[inline]
750            fn index(&self, index: I) -> &$ustr {
751                &self.as_ustr()[index]
752            }
753        }
754
755        impl<I> IndexMut<I> for $ustring
756        where
757            I: SliceIndex<[$uchar], Output = [$uchar]>,
758        {
759            fn index_mut(&mut self, index: I) -> &mut Self::Output {
760                &mut self.as_mut_ustr()[index]
761            }
762        }
763
764        impl PartialEq<$ustr> for $ustring {
765            #[inline]
766            fn eq(&self, other: &$ustr) -> bool {
767                self.as_ustr() == other
768            }
769        }
770
771        impl PartialEq<$ucstr> for $ustring {
772            #[inline]
773            fn eq(&self, other: &$ucstr) -> bool {
774                self.as_ustr() == other
775            }
776        }
777
778        impl PartialEq<$ucstring> for $ustring {
779            #[inline]
780            fn eq(&self, other: &$ucstring) -> bool {
781                self.as_ustr() == other.as_ucstr()
782            }
783        }
784
785        impl<'a> PartialEq<&'a $ustr> for $ustring {
786            #[inline]
787            fn eq(&self, other: &&'a $ustr) -> bool {
788                self.as_ustr() == *other
789            }
790        }
791
792        impl<'a> PartialEq<&'a $ucstr> for $ustring {
793            #[inline]
794            fn eq(&self, other: &&'a $ucstr) -> bool {
795                self.as_ustr() == *other
796            }
797        }
798
799        impl<'a> PartialEq<Cow<'a, $ustr>> for $ustring {
800            #[inline]
801            fn eq(&self, other: &Cow<'a, $ustr>) -> bool {
802                self.as_ustr() == other.as_ref()
803            }
804        }
805
806        impl<'a> PartialEq<Cow<'a, $ucstr>> for $ustring {
807            #[inline]
808            fn eq(&self, other: &Cow<'a, $ucstr>) -> bool {
809                self.as_ustr() == other.as_ref()
810            }
811        }
812
813        impl PartialEq<$ustring> for $ustr {
814            #[inline]
815            fn eq(&self, other: &$ustring) -> bool {
816                self == other.as_ustr()
817            }
818        }
819
820        impl PartialEq<$ustring> for $ucstr {
821            #[inline]
822            fn eq(&self, other: &$ustring) -> bool {
823                self.as_ustr() == other.as_ustr()
824            }
825        }
826
827        impl PartialEq<$ustring> for &$ustr {
828            #[inline]
829            fn eq(&self, other: &$ustring) -> bool {
830                self == other.as_ustr()
831            }
832        }
833
834        impl PartialEq<$ustring> for &$ucstr {
835            #[inline]
836            fn eq(&self, other: &$ustring) -> bool {
837                self.as_ustr() == other.as_ustr()
838            }
839        }
840
841        impl PartialOrd<$ustr> for $ustring {
842            #[inline]
843            fn partial_cmp(&self, other: &$ustr) -> Option<cmp::Ordering> {
844                self.as_ustr().partial_cmp(other)
845            }
846        }
847
848        impl PartialOrd<$ucstr> for $ustring {
849            #[inline]
850            fn partial_cmp(&self, other: &$ucstr) -> Option<cmp::Ordering> {
851                self.as_ustr().partial_cmp(other)
852            }
853        }
854
855        impl<'a> PartialOrd<&'a $ustr> for $ustring {
856            #[inline]
857            fn partial_cmp(&self, other: &&'a $ustr) -> Option<cmp::Ordering> {
858                self.as_ustr().partial_cmp(*other)
859            }
860        }
861
862        impl<'a> PartialOrd<&'a $ucstr> for $ustring {
863            #[inline]
864            fn partial_cmp(&self, other: &&'a $ucstr) -> Option<cmp::Ordering> {
865                self.as_ustr().partial_cmp(*other)
866            }
867        }
868
869        impl<'a> PartialOrd<Cow<'a, $ustr>> for $ustring {
870            #[inline]
871            fn partial_cmp(&self, other: &Cow<'a, $ustr>) -> Option<cmp::Ordering> {
872                self.as_ustr().partial_cmp(other.as_ref())
873            }
874        }
875
876        impl<'a> PartialOrd<Cow<'a, $ucstr>> for $ustring {
877            #[inline]
878            fn partial_cmp(&self, other: &Cow<'a, $ucstr>) -> Option<cmp::Ordering> {
879                self.as_ustr().partial_cmp(other.as_ref())
880            }
881        }
882
883        impl PartialOrd<$ucstring> for $ustring {
884            #[inline]
885            fn partial_cmp(&self, other: &$ucstring) -> Option<cmp::Ordering> {
886                self.as_ustr().partial_cmp(other.as_ucstr())
887            }
888        }
889
890        impl ToOwned for $ustr {
891            type Owned = $ustring;
892
893            #[inline]
894            fn to_owned(&self) -> $ustring {
895                self.to_ustring()
896            }
897        }
898
899        impl Write for $ustring {
900            #[inline]
901            fn write_str(&mut self, s: &str) -> core::fmt::Result {
902                self.push_str(s);
903                Ok(())
904            }
905
906            #[inline]
907            fn write_char(&mut self, c: char) -> core::fmt::Result {
908                self.push_char(c);
909                Ok(())
910            }
911        }
912    };
913}
914
915ustring_common_impl! {
916    /// An owned, mutable 16-bit wide string with undefined encoding.
917    ///
918    /// The string slice of a [`U16String`] is [`U16Str`].
919    ///
920    /// [`U16String`] are strings that do not have a defined encoding. While it is sometimes
921    /// assumed that they contain possibly invalid or ill-formed UTF-16 data, they may be used for
922    /// any wide encoded string. This is because [`U16String`] is intended to be used with FFI
923    /// functions, where proper encoding cannot be guaranteed. If you need string slices that are
924    /// always valid UTF-16 strings, use [`Utf16String`][crate::Utf16String] instead.
925    ///
926    /// Because [`U16String`] does not have a defined encoding, no restrictions are placed on
927    /// mutating or indexing the string. This means that even if the string contained properly
928    /// encoded UTF-16 or other encoding data, mutationing or indexing may result in malformed data.
929    /// Convert to a [`Utf16String`][crate::Utf16String] if retaining proper UTF-16 encoding is
930    /// desired.
931    ///
932    /// # FFI considerations
933    ///
934    /// [`U16String`] is not aware of nul values. Strings may or may not be nul-terminated, and may
935    /// contain invalid and ill-formed UTF-16. These strings are intended to be used with FFI functions
936    /// that directly use string length, where the strings are known to have proper nul-termination
937    /// already, or where strings are merely being passed through without modification.
938    ///
939    /// [`U16CString`][crate::U16CString] should be used instead if nul-aware strings are required.
940    ///
941    /// # Examples
942    ///
943    /// The easiest way to use [`U16String`] outside of FFI is with the [`u16str!`][crate::u16str]
944    /// macro to convert string literals into UTF-16 string slices at compile time:
945    ///
946    /// ```
947    /// use widestring::{u16str, U16String};
948    /// let hello = U16String::from(u16str!("Hello, world!"));
949    /// ```
950    ///
951    /// You can also convert any [`u16`] slice or vector directly:
952    ///
953    /// ```
954    /// use widestring::{u16str, U16String};
955    ///
956    /// let sparkle_heart = vec![0xd83d, 0xdc96];
957    /// let sparkle_heart = U16String::from_vec(sparkle_heart);
958    ///
959    /// assert_eq!(u16str!("💖"), sparkle_heart);
960    ///
961    /// // This unpaired UTf-16 surrogate is invalid UTF-16, but is perfectly valid in U16String
962    /// let malformed_utf16 = vec![0x0, 0xd83d]; // Note that nul values are also valid an untouched
963    /// let s = U16String::from_vec(malformed_utf16);
964    ///
965    /// assert_eq!(s.len(), 2);
966    /// ```
967    ///
968    /// The following example constructs a [`U16String`] and shows how to convert a [`U16String`] to
969    /// a regular Rust [`String`].
970    ///
971    /// ```rust
972    /// use widestring::U16String;
973    /// let s = "Test";
974    /// // Create a wide string from the rust string
975    /// let wstr = U16String::from_str(s);
976    /// // Convert back to a rust string
977    /// let rust_str = wstr.to_string_lossy();
978    /// assert_eq!(rust_str, "Test");
979    /// ```
980    struct U16String([u16]);
981
982    type UStr = U16Str;
983    type UCString = U16CString;
984    type UCStr = U16CStr;
985    type UtfStr = Utf16Str;
986    type UtfString = Utf16String;
987
988    /// Extends the string with the given string slice.
989    ///
990    /// No checks are performed on the strings. It is possible to end up nul values inside
991    /// the string, or invalid encoding, and it is up to the caller to determine if that is
992    /// acceptable.
993    ///
994    /// # Examples
995    ///
996    /// ```rust
997    /// use widestring::U16String;
998    /// let s = "MyString";
999    /// let mut wstr = U16String::from_str(s);
1000    /// let cloned = wstr.clone();
1001    /// // Push the clone to the end, repeating the string twice.
1002    /// wstr.push(cloned);
1003    ///
1004    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1005    /// ```
1006    fn push() -> {}
1007
1008    /// Extends the string with the given slice.
1009    ///
1010    /// No checks are performed on the strings. It is possible to end up nul values inside
1011    /// the string, or invalid encoding, and it is up to the caller to determine if that is
1012    /// acceptable.
1013    ///
1014    /// # Examples
1015    ///
1016    /// ```rust
1017    /// use widestring::U16String;
1018    /// let s = "MyString";
1019    /// let mut wstr = U16String::from_str(s);
1020    /// let cloned = wstr.clone();
1021    /// // Push the clone to the end, repeating the string twice.
1022    /// wstr.push_slice(cloned);
1023    ///
1024    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1025    /// ```
1026    fn push_slice() -> {}
1027
1028    /// Converts this wide string into a boxed string slice.
1029    ///
1030    /// # Examples
1031    ///
1032    /// ```
1033    /// use widestring::{U16String, U16Str};
1034    ///
1035    /// let s = U16String::from_str("hello");
1036    ///
1037    /// let b: Box<U16Str> = s.into_boxed_ustr();
1038    /// ```
1039    fn into_boxed_ustr() -> {}
1040}
1041
1042ustring_common_impl! {
1043    /// An owned, mutable 32-bit wide string with undefined encoding.
1044    ///
1045    /// The string slice of a [`U32String`] is [`U32Str`].
1046    ///
1047    /// [`U32String`] are strings that do not have a defined encoding. While it is sometimes
1048    /// assumed that they contain possibly invalid or ill-formed UTF-32 data, they may be used for
1049    /// any wide encoded string. This is because [`U32String`] is intended to be used with FFI
1050    /// functions, where proper encoding cannot be guaranteed. If you need string slices that are
1051    /// always valid UTF-32 strings, use [`Utf32String`][crate::Utf32String] instead.
1052    ///
1053    /// Because [`U32String`] does not have a defined encoding, no restrictions are placed on
1054    /// mutating or indexing the string. This means that even if the string contained properly
1055    /// encoded UTF-32 or other encoding data, mutationing or indexing may result in malformed data.
1056    /// Convert to a [`Utf32String`][crate::Utf32String] if retaining proper UTF-16 encoding is
1057    /// desired.
1058    ///
1059    /// # FFI considerations
1060    ///
1061    /// [`U32String`] is not aware of nul values. Strings may or may not be nul-terminated, and may
1062    /// contain invalid and ill-formed UTF-32. These strings are intended to be used with FFI functions
1063    /// that directly use string length, where the strings are known to have proper nul-termination
1064    /// already, or where strings are merely being passed through without modification.
1065    ///
1066    /// [`U32CString`][crate::U32CString] should be used instead if nul-aware strings are required.
1067    ///
1068    /// # Examples
1069    ///
1070    /// The easiest way to use [`U32String`] outside of FFI is with the [`u32str!`][crate::u32str]
1071    /// macro to convert string literals into UTF-32 string slices at compile time:
1072    ///
1073    /// ```
1074    /// use widestring::{u32str, U32String};
1075    /// let hello = U32String::from(u32str!("Hello, world!"));
1076    /// ```
1077    ///
1078    /// You can also convert any [`u32`] slice or vector directly:
1079    ///
1080    /// ```
1081    /// use widestring::{u32str, U32String};
1082    ///
1083    /// let sparkle_heart = vec![0x1f496];
1084    /// let sparkle_heart = U32String::from_vec(sparkle_heart);
1085    ///
1086    /// assert_eq!(u32str!("💖"), sparkle_heart);
1087    ///
1088    /// // This UTf-16 surrogate is invalid UTF-32, but is perfectly valid in U32String
1089    /// let malformed_utf32 = vec![0x0, 0xd83d]; // Note that nul values are also valid an untouched
1090    /// let s = U32String::from_vec(malformed_utf32);
1091    ///
1092    /// assert_eq!(s.len(), 2);
1093    /// ```
1094    ///
1095    /// The following example constructs a [`U32String`] and shows how to convert a [`U32String`] to
1096    /// a regular Rust [`String`].
1097    ///
1098    /// ```rust
1099    /// use widestring::U32String;
1100    /// let s = "Test";
1101    /// // Create a wide string from the rust string
1102    /// let wstr = U32String::from_str(s);
1103    /// // Convert back to a rust string
1104    /// let rust_str = wstr.to_string_lossy();
1105    /// assert_eq!(rust_str, "Test");
1106    /// ```
1107    struct U32String([u32]);
1108
1109    type UStr = U32Str;
1110    type UCString = U32CString;
1111    type UCStr = U32CStr;
1112    type UtfStr = Utf32Str;
1113    type UtfString = Utf32String;
1114
1115    /// Extends the string with the given string slice.
1116    ///
1117    /// No checks are performed on the strings. It is possible to end up nul values inside
1118    /// the string, or invalid encoding, and it is up to the caller to determine if that is
1119    /// acceptable.
1120    ///
1121    /// # Examples
1122    ///
1123    /// ```rust
1124    /// use widestring::U32String;
1125    /// let s = "MyString";
1126    /// let mut wstr = U32String::from_str(s);
1127    /// let cloned = wstr.clone();
1128    /// // Push the clone to the end, repeating the string twice.
1129    /// wstr.push(cloned);
1130    ///
1131    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1132    /// ```
1133    fn push() -> {}
1134
1135    /// Extends the string with the given slice.
1136    ///
1137    /// No checks are performed on the strings. It is possible to end up nul values inside
1138    /// the string, or invalid encoding, and it is up to the caller to determine if that is
1139    /// acceptable.
1140    ///
1141    /// # Examples
1142    ///
1143    /// ```rust
1144    /// use widestring::U32String;
1145    /// let s = "MyString";
1146    /// let mut wstr = U32String::from_str(s);
1147    /// let cloned = wstr.clone();
1148    /// // Push the clone to the end, repeating the string twice.
1149    /// wstr.push_slice(cloned);
1150    ///
1151    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1152    /// ```
1153    fn push_slice() -> {}
1154
1155    /// Converts this wide string into a boxed string slice.
1156    ///
1157    /// # Examples
1158    ///
1159    /// ```
1160    /// use widestring::{U32String, U32Str};
1161    ///
1162    /// let s = U32String::from_str("hello");
1163    ///
1164    /// let b: Box<U32Str> = s.into_boxed_ustr();
1165    /// ```
1166    fn into_boxed_ustr() -> {}
1167}
1168
1169impl U16String {
1170    /// Constructs a [`U16String`] copy from a [`str`], encoding it as UTF-16.
1171    ///
1172    /// This makes a string copy of the [`str`]. Since [`str`] will always be valid UTF-8, the
1173    /// resulting [`U16String`] will also be valid UTF-16.
1174    ///
1175    /// # Examples
1176    ///
1177    /// ```rust
1178    /// use widestring::U16String;
1179    /// let s = "MyString";
1180    /// // Create a wide string from the string
1181    /// let wstr = U16String::from_str(s);
1182    ///
1183    /// assert_eq!(wstr.to_string().unwrap(), s);
1184    /// ```
1185    #[allow(clippy::should_implement_trait)]
1186    #[inline]
1187    #[must_use]
1188    pub fn from_str<S: AsRef<str> + ?Sized>(s: &S) -> Self {
1189        Self {
1190            inner: s.as_ref().encode_utf16().collect(),
1191        }
1192    }
1193
1194    /// Constructs a [`U16String`] copy from an [`OsStr`][std::ffi::OsStr].
1195    ///
1196    /// This makes a string copy of the [`OsStr`][std::ffi::OsStr]. Since [`OsStr`][std::ffi::OsStr]
1197    /// makes no guarantees that it is valid data, there is no guarantee that the resulting
1198    /// [`U16String`] will be valid UTF-16.
1199    ///
1200    /// Note that the encoding of [`OsStr`][std::ffi::OsStr] is platform-dependent, so on
1201    /// some platforms this may make an encoding conversions, while on other platforms (such as
1202    /// windows) no changes to the string will be made.
1203    ///
1204    /// # Examples
1205    ///
1206    /// ```rust
1207    /// use widestring::U16String;
1208    /// let s = "MyString";
1209    /// // Create a wide string from the string
1210    /// let wstr = U16String::from_os_str(s);
1211    ///
1212    /// assert_eq!(wstr.to_string().unwrap(), s);
1213    /// ```
1214    #[cfg(feature = "std")]
1215    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1216    #[inline]
1217    #[must_use]
1218    pub fn from_os_str<S: AsRef<std::ffi::OsStr> + ?Sized>(s: &S) -> Self {
1219        Self {
1220            inner: crate::platform::os_to_wide(s.as_ref()),
1221        }
1222    }
1223
1224    /// Extends the string with the given string slice, encoding it at UTF-16.
1225    ///
1226    /// No checks are performed on the strings. It is possible to end up nul values inside the
1227    /// string, and it is up to the caller to determine if that is acceptable.
1228    ///
1229    /// # Examples
1230    ///
1231    /// ```rust
1232    /// use widestring::U16String;
1233    /// let s = "MyString";
1234    /// let mut wstr = U16String::from_str(s);
1235    /// // Push the original to the end, repeating the string twice.
1236    /// wstr.push_str(s);
1237    ///
1238    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1239    /// ```
1240    #[inline]
1241    pub fn push_str(&mut self, s: impl AsRef<str>) {
1242        self.inner.extend(s.as_ref().encode_utf16())
1243    }
1244
1245    /// Extends the string with the given string slice.
1246    ///
1247    /// No checks are performed on the strings. It is possible to end up nul values inside the
1248    /// string, and it is up to the caller to determine if that is acceptable.
1249    ///
1250    /// # Examples
1251    ///
1252    /// ```rust
1253    /// use widestring::U16String;
1254    /// let s = "MyString";
1255    /// let mut wstr = U16String::from_str(s);
1256    /// // Push the original to the end, repeating the string twice.
1257    /// wstr.push_os_str(s);
1258    ///
1259    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1260    /// ```
1261    #[cfg(feature = "std")]
1262    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1263    #[inline]
1264    pub fn push_os_str(&mut self, s: impl AsRef<std::ffi::OsStr>) {
1265        self.inner.extend(crate::platform::os_to_wide(s.as_ref()))
1266    }
1267
1268    /// Appends the given [`char`][prim@char] encoded as UTF-16 to the end of this string.
1269    #[inline]
1270    pub fn push_char(&mut self, c: char) {
1271        let mut buf = [0; 2];
1272        self.inner.extend_from_slice(c.encode_utf16(&mut buf))
1273    }
1274
1275    /// Removes the last character or unpaired surrogate from the string buffer and returns it.
1276    ///
1277    /// This method assumes UTF-16 encoding, but handles invalid UTF-16 by returning unpaired
1278    /// surrogates.
1279    ///
1280    /// Returns `None` if this String is empty. Otherwise, returns the character cast to a
1281    /// [`u32`][prim@u32] or the value of the unpaired surrogate as a [`u32`][prim@u32] value.
1282    pub fn pop_char(&mut self) -> Option<u32> {
1283        match self.inner.pop() {
1284            Some(low) if crate::is_utf16_surrogate(low) => {
1285                if !crate::is_utf16_low_surrogate(low) || self.inner.is_empty() {
1286                    Some(low as u32)
1287                } else {
1288                    let high = self.inner[self.len() - 1];
1289                    if crate::is_utf16_high_surrogate(high) {
1290                        self.inner.pop();
1291                        let buf = [high, low];
1292                        Some(
1293                            char::decode_utf16(buf.iter().copied())
1294                                .next()
1295                                .unwrap()
1296                                .unwrap() as u32,
1297                        )
1298                    } else {
1299                        Some(low as u32)
1300                    }
1301                }
1302            }
1303            Some(u) => Some(u as u32),
1304            None => None,
1305        }
1306    }
1307
1308    /// Removes a [`char`][prim@char] or unpaired surrogate from this string at a position and
1309    /// returns it as a [`u32`][prim@u32].
1310    ///
1311    /// This method assumes UTF-16 encoding, but handles invalid UTF-16 by returning unpaired
1312    /// surrogates.
1313    ///
1314    /// This is an _O(n)_ operation, as it requires copying every element in the buffer.
1315    ///
1316    /// # Panics
1317    ///
1318    /// Panics if `idx` is larger than or equal to the string's length.
1319    pub fn remove_char(&mut self, idx: usize) -> u32 {
1320        let slice = &self.inner[idx..];
1321        let c = char::decode_utf16(slice.iter().copied()).next().unwrap();
1322        let clen = c.as_ref().map(|c| c.len_utf16()).unwrap_or(1);
1323        let c = c
1324            .map(|c| c as u32)
1325            .unwrap_or_else(|_| self.inner[idx] as u32);
1326        self.inner.drain(idx..idx + clen);
1327        c
1328    }
1329
1330    /// Inserts a character encoded as UTF-16 into this string at a specified position.
1331    ///
1332    /// This is an _O(n)_ operation as it requires copying every element in the buffer.
1333    ///
1334    /// # Panics
1335    ///
1336    /// Panics if `idx` is larger than the string's length.
1337    pub fn insert_char(&mut self, idx: usize, c: char) {
1338        assert!(idx <= self.len());
1339        let mut buf = [0; 2];
1340        let slice = c.encode_utf16(&mut buf);
1341        self.inner.resize(self.len() + slice.len(), 0);
1342        self.inner.copy_within(idx.., idx + slice.len());
1343        self.inner[idx..].copy_from_slice(slice);
1344    }
1345}
1346
1347impl U32String {
1348    /// Constructs a [`U32String`] from a [`char`][prim@char] vector.
1349    ///
1350    /// No checks are made on the contents of the vector.
1351    ///
1352    /// # Examples
1353    ///
1354    /// ```rust
1355    /// use widestring::U32String;
1356    /// let v: Vec<char> = "Test".chars().collect();
1357    /// # let cloned: Vec<u32> = v.iter().map(|&c| c as u32).collect();
1358    /// // Create a wide string from the vector
1359    /// let wstr = U32String::from_chars(v);
1360    /// # assert_eq!(wstr.into_vec(), cloned);
1361    /// ```
1362    #[must_use]
1363    pub fn from_chars(raw: impl Into<Vec<char>>) -> Self {
1364        let mut chars = raw.into();
1365        Self {
1366            inner: unsafe {
1367                let ptr = chars.as_mut_ptr() as *mut u32;
1368                let len = chars.len();
1369                let cap = chars.capacity();
1370                mem::forget(chars);
1371                Vec::from_raw_parts(ptr, len, cap)
1372            },
1373        }
1374    }
1375
1376    /// Constructs a [`U16String`] copy from a [`str`], encoding it as UTF-32.
1377    ///
1378    /// This makes a string copy of the [`str`]. Since [`str`] will always be valid UTF-8, the
1379    /// resulting [`U32String`] will also be valid UTF-32.
1380    ///
1381    /// # Examples
1382    ///
1383    /// ```rust
1384    /// use widestring::U32String;
1385    /// let s = "MyString";
1386    /// // Create a wide string from the string
1387    /// let wstr = U32String::from_str(s);
1388    ///
1389    /// assert_eq!(wstr.to_string().unwrap(), s);
1390    /// ```
1391    #[allow(clippy::should_implement_trait)]
1392    #[inline]
1393    #[must_use]
1394    pub fn from_str<S: AsRef<str> + ?Sized>(s: &S) -> Self {
1395        let v: Vec<char> = s.as_ref().chars().collect();
1396        Self::from_chars(v)
1397    }
1398
1399    /// Constructs a [`U32String`] copy from an [`OsStr`][std::ffi::OsStr].
1400    ///
1401    /// This makes a string copy of the [`OsStr`][std::ffi::OsStr]. Since [`OsStr`][std::ffi::OsStr]
1402    /// makes no guarantees that it is valid data, there is no guarantee that the resulting
1403    /// [`U32String`] will be valid UTF-32.
1404    ///
1405    /// Note that the encoding of [`OsStr`][std::ffi::OsStr] is platform-dependent, so on
1406    /// some platforms this may make an encoding conversions, while on other platforms no changes to
1407    /// the string will be made.
1408    ///
1409    /// # Examples
1410    ///
1411    /// ```rust
1412    /// use widestring::U32String;
1413    /// let s = "MyString";
1414    /// // Create a wide string from the string
1415    /// let wstr = U32String::from_os_str(s);
1416    ///
1417    /// assert_eq!(wstr.to_string().unwrap(), s);
1418    /// ```
1419    #[cfg(feature = "std")]
1420    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1421    #[must_use]
1422    pub fn from_os_str<S: AsRef<std::ffi::OsStr> + ?Sized>(s: &S) -> Self {
1423        let v: Vec<char> = s.as_ref().to_string_lossy().chars().collect();
1424        Self::from_chars(v)
1425    }
1426
1427    /// Constructs a [`U32String`] from a [`char`][prim@char] pointer and a length.
1428    ///
1429    /// The `len` argument is the number of `char` elements, **not** the number of bytes.
1430    ///
1431    /// # Safety
1432    ///
1433    /// This function is unsafe as there is no guarantee that the given pointer is valid for `len`
1434    /// elements.
1435    ///
1436    /// In addition, the data must meet the safety conditions of [std::slice::from_raw_parts].
1437    ///
1438    /// # Panics
1439    ///
1440    /// Panics if `len` is greater than 0 but `p` is a null pointer.
1441    #[inline]
1442    #[must_use]
1443    pub unsafe fn from_char_ptr(p: *const char, len: usize) -> Self {
1444        Self::from_ptr(p as *const u32, len)
1445    }
1446
1447    /// Extends the string with the given string slice, encoding it at UTF-32.
1448    ///
1449    /// No checks are performed on the strings. It is possible to end up nul values inside the
1450    /// string, and it is up to the caller to determine if that is acceptable.
1451    ///
1452    /// # Examples
1453    ///
1454    /// ```rust
1455    /// use widestring::U32String;
1456    /// let s = "MyString";
1457    /// let mut wstr = U32String::from_str(s);
1458    /// // Push the original to the end, repeating the string twice.
1459    /// wstr.push_str(s);
1460    ///
1461    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1462    /// ```
1463    #[inline]
1464    pub fn push_str(&mut self, s: impl AsRef<str>) {
1465        self.inner.extend(s.as_ref().chars().map(|c| c as u32))
1466    }
1467
1468    /// Extends the string with the given string slice.
1469    ///
1470    /// No checks are performed on the strings. It is possible to end up nul values inside the
1471    /// string, and it is up to the caller to determine if that is acceptable.
1472    ///
1473    /// # Examples
1474    ///
1475    /// ```rust
1476    /// use widestring::U32String;
1477    /// let s = "MyString";
1478    /// let mut wstr = U32String::from_str(s);
1479    /// // Push the original to the end, repeating the string twice.
1480    /// wstr.push_os_str(s);
1481    ///
1482    /// assert_eq!(wstr.to_string().unwrap(), "MyStringMyString");
1483    /// ```
1484    #[cfg(feature = "std")]
1485    #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
1486    #[inline]
1487    pub fn push_os_str(&mut self, s: impl AsRef<std::ffi::OsStr>) {
1488        self.inner
1489            .extend(s.as_ref().to_string_lossy().chars().map(|c| c as u32))
1490    }
1491
1492    /// Appends the given [`char`][prim@char] encoded as UTF-32 to the end of this string.
1493    #[inline]
1494    pub fn push_char(&mut self, c: char) {
1495        self.inner.push(c as u32);
1496    }
1497
1498    /// Removes the last value from the string buffer and returns it.
1499    ///
1500    /// This method assumes UTF-32 encoding.
1501    ///
1502    /// Returns `None` if this String is empty.
1503    #[inline]
1504    pub fn pop_char(&mut self) -> Option<u32> {
1505        self.inner.pop()
1506    }
1507
1508    /// Removes a value from this string at a position and returns it.
1509    ///
1510    /// This method assumes UTF-32 encoding.
1511    ///
1512    /// This is an _O(n)_ operation, as it requires copying every element in the buffer.
1513    ///
1514    /// # Panics
1515    ///
1516    /// Panics if `idx` is larger than or equal to the string's length.
1517    #[inline]
1518    pub fn remove_char(&mut self, idx: usize) -> u32 {
1519        self.inner.remove(idx)
1520    }
1521
1522    /// Inserts a character encoded as UTF-32 into this string at a specified position.
1523    ///
1524    /// This is an _O(n)_ operation as it requires copying every element in the buffer.
1525    ///
1526    /// # Panics
1527    ///
1528    /// Panics if `idx` is larger than the string's length.
1529    #[inline]
1530    pub fn insert_char(&mut self, idx: usize, c: char) {
1531        self.inner.insert(idx, c as u32)
1532    }
1533}
1534
1535impl core::fmt::Debug for U16String {
1536    #[inline]
1537    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1538        crate::debug_fmt_u16(self.as_slice(), f)
1539    }
1540}
1541
1542impl core::fmt::Debug for U32String {
1543    #[inline]
1544    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1545        crate::debug_fmt_u32(self.as_slice(), f)
1546    }
1547}
1548
1549impl From<Vec<char>> for U32String {
1550    #[inline]
1551    fn from(value: Vec<char>) -> Self {
1552        Self::from_chars(value)
1553    }
1554}
1555
1556impl From<&[char]> for U32String {
1557    #[inline]
1558    fn from(value: &[char]) -> Self {
1559        U32String::from_chars(value)
1560    }
1561}
1562
1563/// Alias for [`U16String`] or [`U32String`] depending on platform. Intended to match typical C
1564/// `wchar_t` size on platform.
1565#[cfg(not(windows))]
1566pub type WideString = U32String;
1567
1568/// Alias for [`U16String`] or [`U32String`] depending on platform. Intended to match typical C
1569/// `wchar_t` size on platform.
1570#[cfg(windows)]
1571pub type WideString = U16String;
1572
1573#[cfg(test)]
1574mod test {
1575    use super::*;
1576
1577    #[test]
1578    #[allow(clippy::write_literal)]
1579    fn number_to_string() {
1580        let mut s = U16String::new();
1581        write!(s, "{}", 1234).unwrap();
1582        assert_eq!(s, U16String::from_str("1234"));
1583    }
1584
1585    #[test]
1586    fn truncated_with_surrogate() {
1587        // Character U+24B62, encoded as D852 DF62 in UTF16
1588        let buf = "𤭢";
1589        let mut s = U16String::from_str(buf);
1590        assert_eq!(s.pop_char(), Some('𤭢' as u32));
1591    }
1592}