generic_str/
traits_utf8.rs

1use generic_vec::raw::Storage;
2
3#[cfg(feature = "alloc")]
4use generic_vec::HeapVec;
5#[cfg(feature = "alloc")]
6use std::{
7    borrow::Cow,
8    ops::{Add, AddAssign},
9};
10
11use crate::{string_base::StringBase, OwnedString};
12use core::{
13    ops::{Index, IndexMut},
14    slice::SliceIndex,
15};
16
17impl AsRef<str> for StringBase<[u8]> {
18    fn as_ref(&self) -> &str {
19        unsafe { core::str::from_utf8_unchecked(&self.storage) }
20    }
21}
22
23impl AsMut<str> for StringBase<[u8]> {
24    fn as_mut(&mut self) -> &mut str {
25        unsafe { core::str::from_utf8_unchecked_mut(&mut self.storage) }
26    }
27}
28
29impl<I> Index<I> for StringBase<[u8]>
30where
31    I: SliceIndex<StringBase<[u8]>>,
32{
33    type Output = I::Output;
34
35    #[inline]
36    fn index(&self, index: I) -> &I::Output {
37        index.index(self)
38    }
39}
40
41impl<I> IndexMut<I> for StringBase<[u8]>
42where
43    I: SliceIndex<StringBase<[u8]>>,
44{
45    #[inline]
46    fn index_mut(&mut self, index: I) -> &mut I::Output {
47        index.index_mut(self)
48    }
49}
50
51impl<S: ?Sized + Storage<Item = u8>> core::fmt::Debug for OwnedString<u8, S> {
52    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
53        let s: &StringBase<[S::Item]> = self.as_ref();
54        let s: &str = s.as_ref();
55        write!(f, "{:?}", s)
56    }
57}
58
59impl<S: ?Sized + Storage<Item = u8>> core::fmt::Display for OwnedString<u8, S> {
60    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
61        let s: &StringBase<[S::Item]> = self.as_ref();
62        let s: &str = s.as_ref();
63        write!(f, "{}", s)
64    }
65}
66
67impl core::fmt::Debug for StringBase<[u8]> {
68    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
69        let s: &str = self.as_ref();
70        write!(f, "{:?}", s)
71    }
72}
73
74impl core::fmt::Display for StringBase<[u8]> {
75    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
76        let s: &str = self.as_ref();
77        write!(f, "{}", s)
78    }
79}
80
81#[cfg(feature = "alloc")]
82impl From<String> for StringBase<HeapVec<u8>> {
83    fn from(s: String) -> Self {
84        let (ptr, len, capacity) = s.into_raw_parts();
85        unsafe {
86            let ptr = std::ptr::slice_from_raw_parts_mut(ptr.cast(), capacity);
87            let storage = Box::from_raw(ptr);
88            let storage = HeapVec::from_raw_parts(len, storage);
89            Self { storage }
90        }
91    }
92}
93
94#[cfg(feature = "alloc")]
95impl From<&str> for StringBase<HeapVec<u8>> {
96    fn from(s: &str) -> Self {
97        s.to_owned().into()
98    }
99}
100
101impl From<&str> for &StringBase<[u8]> {
102    fn from(s: &str) -> Self {
103        unsafe { core::mem::transmute(s) }
104    }
105}
106
107impl From<&mut str> for &mut StringBase<[u8]> {
108    fn from(s: &mut str) -> Self {
109        unsafe { core::mem::transmute(s) }
110    }
111}
112
113impl<'a, S: ?Sized + AsRef<[u8]>> From<&'a StringBase<S>> for &'a str {
114    fn from(s: &'a StringBase<S>) -> Self {
115        unsafe { core::str::from_utf8_unchecked(s.storage.as_ref()) }
116    }
117}
118
119#[cfg(feature = "alloc")]
120impl<'a> Add<&'a crate::str> for Cow<'a, crate::str> {
121    type Output = Cow<'a, crate::str>;
122
123    #[inline]
124    fn add(mut self, rhs: &'a crate::str) -> Self::Output {
125        self += rhs;
126        self
127    }
128}
129
130#[cfg(feature = "alloc")]
131impl<'a> AddAssign<&'a crate::str> for Cow<'a, crate::str> {
132    fn add_assign(&mut self, rhs: &'a crate::str) {
133        if self.is_empty() {
134            *self = Cow::Borrowed(rhs)
135        } else if !rhs.is_empty() {
136            if let Cow::Borrowed(lhs) = *self {
137                let mut s = crate::String::with_capacity(lhs.len() + rhs.len());
138                s.push_str(lhs);
139                *self = Cow::Owned(s);
140            }
141            self.to_mut().push_str(rhs);
142        }
143    }
144}