generic_str/
traits_utf8.rs1use 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}