generic_str/
string_base.rs1use core::cmp::Ordering;
2
3use generic_vec::{
4 raw::{Storage, StorageWithCapacity},
5 GenericVec,
6};
7
8#[cfg(feature = "alloc")]
9use generic_vec::HeapVec;
10#[cfg(feature = "alloc")]
11use std::{alloc::Allocator, borrow::Borrow};
12
13#[derive(Default, Copy, Clone)]
14#[repr(transparent)]
15pub struct StringBase<S: ?Sized> {
16 pub(crate) storage: S,
17}
18
19impl<S: StorageWithCapacity> StringBase<GenericVec<S::Item, S>> {
20 #[inline]
21 pub fn new_with_capacity(capacity: usize) -> Self {
22 Self::with_storage(S::with_capacity(capacity))
23 }
24}
25
26pub type OwnedString<T, S> = StringBase<GenericVec<T, S>>;
27pub type StringSlice<U> = StringBase<[U]>;
28
29impl<S: ?Sized + Storage> StringBase<GenericVec<S::Item, S>> {
30 #[inline]
69 pub fn with_storage(storage: S) -> Self
70 where
71 S: Sized,
72 {
73 StringBase {
74 storage: GenericVec::with_storage(storage),
75 }
76 }
77}
78
79impl<T: ?Sized + core::ops::Deref> core::ops::Deref for StringBase<T> {
80 type Target = StringBase<T::Target>;
81
82 fn deref(&self) -> &StringBase<T::Target> {
83 unsafe { core::mem::transmute::<&T::Target, &StringBase<T::Target>>(self.storage.deref()) }
84 }
85}
86
87impl<T: ?Sized + core::ops::DerefMut> core::ops::DerefMut for StringBase<T> {
88 fn deref_mut(&mut self) -> &mut StringBase<T::Target> {
89 unsafe {
90 core::mem::transmute::<&mut T::Target, &mut StringBase<T::Target>>(
91 self.storage.deref_mut(),
92 )
93 }
94 }
95}
96
97impl<T: ?Sized + AsRef<U>, U: ?Sized> AsRef<StringBase<U>> for StringBase<T> {
98 fn as_ref(&self) -> &StringBase<U> {
99 unsafe { core::mem::transmute::<&U, &StringBase<U>>(self.storage.as_ref()) }
100 }
101}
102
103impl<T: ?Sized + AsMut<U>, U: ?Sized> AsMut<StringBase<U>> for StringBase<T> {
104 fn as_mut(&mut self) -> &mut StringBase<U> {
105 unsafe { core::mem::transmute::<&mut U, &mut StringBase<U>>(self.storage.as_mut()) }
106 }
107}
108
109#[cfg(feature = "alloc")]
110impl<T, A: Allocator> Borrow<StringBase<[T]>> for StringBase<HeapVec<T, A>> {
111 fn borrow(&self) -> &StringBase<[T]> {
112 unsafe { std::mem::transmute::<&[T], &StringBase<[T]>>(self.storage.borrow()) }
113 }
114}
115
116#[cfg(feature = "alloc")]
117impl<T: Clone> ToOwned for StringBase<[T]> {
118 type Owned = StringBase<HeapVec<T>>;
119
120 fn to_owned(&self) -> Self::Owned {
121 Self::Owned {
122 storage: self.storage.to_owned().into(),
123 }
124 }
125}
126
127impl<S: ?Sized + Storage, T: ?Sized + Storage> PartialEq<OwnedString<T::Item, T>>
128 for StringBase<GenericVec<S::Item, S>>
129where
130 GenericVec<S::Item, S>: PartialEq<GenericVec<T::Item, T>>,
131{
132 fn eq(&self, other: &OwnedString<T::Item, T>) -> bool {
133 self.storage.eq(&other.storage)
134 }
135}
136
137impl<S: ?Sized + Storage> PartialEq<OwnedString<S::Item, S>> for StringSlice<S::Item>
138where
139 S::Item: PartialEq,
140{
141 fn eq(&self, other: &OwnedString<S::Item, S>) -> bool {
142 other.storage.eq(&self.storage)
143 }
144}
145
146impl<S: ?Sized + Storage> PartialEq<OwnedString<S::Item, S>> for &StringSlice<S::Item>
147where
148 S::Item: PartialEq,
149{
150 fn eq(&self, other: &OwnedString<S::Item, S>) -> bool {
151 other.storage.eq(&self.storage)
152 }
153}
154
155impl<S: ?Sized + Storage> PartialEq<StringSlice<S::Item>> for OwnedString<S::Item, S>
156where
157 S::Item: PartialEq,
158{
159 fn eq(&self, other: &StringSlice<S::Item>) -> bool {
160 self.storage.eq(&other.storage)
161 }
162}
163
164impl<S: ?Sized + Storage> PartialEq<&StringSlice<S::Item>> for OwnedString<S::Item, S>
165where
166 S::Item: PartialEq,
167{
168 fn eq(&self, other: &&StringSlice<S::Item>) -> bool {
169 self.storage.eq(&other.storage)
170 }
171}
172
173impl<U: PartialEq> PartialEq<StringSlice<U>> for StringSlice<U> {
174 fn eq(&self, other: &StringSlice<U>) -> bool {
175 self.storage.eq(&other.storage)
176 }
177}
178
179impl<S: ?Sized + Storage> Eq for OwnedString<S::Item, S> where S::Item: Eq {}
180impl<U: Eq> Eq for StringSlice<U> {}
181
182impl<S: ?Sized + Storage, T: ?Sized + Storage> PartialOrd<OwnedString<T::Item, T>>
183 for OwnedString<S::Item, S>
184where
185 GenericVec<S::Item, S>: PartialOrd<GenericVec<T::Item, T>>,
186{
187 fn partial_cmp(&self, other: &OwnedString<T::Item, T>) -> Option<Ordering> {
188 self.storage.partial_cmp(&other.storage)
189 }
190}
191
192impl<S: ?Sized + Storage> PartialOrd<OwnedString<S::Item, S>> for StringSlice<S::Item>
193where
194 S::Item: PartialOrd,
195{
196 fn partial_cmp(&self, other: &OwnedString<S::Item, S>) -> Option<Ordering> {
197 other.storage.partial_cmp(&self.storage)
198 }
199}
200
201impl<S: ?Sized + Storage> PartialOrd<OwnedString<S::Item, S>> for &StringSlice<S::Item>
202where
203 S::Item: PartialOrd,
204{
205 fn partial_cmp(&self, other: &OwnedString<S::Item, S>) -> Option<Ordering> {
206 other.storage.partial_cmp(&self.storage)
207 }
208}
209
210impl<S: ?Sized + Storage> PartialOrd<StringSlice<S::Item>> for OwnedString<S::Item, S>
211where
212 S::Item: PartialOrd,
213{
214 fn partial_cmp(&self, other: &StringSlice<S::Item>) -> Option<Ordering> {
215 self.storage.partial_cmp(&other.storage)
216 }
217}
218
219impl<S: ?Sized + Storage> PartialOrd<&StringSlice<S::Item>> for OwnedString<S::Item, S>
220where
221 S::Item: PartialOrd,
222{
223 fn partial_cmp(&self, other: &&StringSlice<S::Item>) -> Option<Ordering> {
224 self.storage.partial_cmp(&other.storage)
225 }
226}
227
228impl<U: PartialOrd> PartialOrd<StringSlice<U>> for StringSlice<U> {
229 fn partial_cmp(&self, other: &StringSlice<U>) -> Option<Ordering> {
230 self.storage.partial_cmp(&other.storage)
231 }
232}
233
234impl<S: ?Sized + Storage> Ord for OwnedString<S::Item, S>
235where
236 S::Item: Ord,
237{
238 fn cmp(&self, other: &Self) -> Ordering {
239 self.storage.cmp(&other.storage)
240 }
241}
242impl<U: Ord> Ord for StringSlice<U> {
243 fn cmp(&self, other: &Self) -> Ordering {
244 self.storage.cmp(&other.storage)
245 }
246}