]> git.proxmox.com Git - rustc.git/blob - vendor/kstring/src/string_cow.rs
New upstream version 1.75.0+dfsg1
[rustc.git] / vendor / kstring / src / string_cow.rs
1 use std::{borrow::Cow, fmt};
2
3 use crate::KStringBase;
4 use crate::KStringRef;
5 use crate::KStringRefInner;
6
7 type StdString = std::string::String;
8 type BoxedStr = Box<str>;
9
10 /// A reference to a UTF-8 encoded, immutable string.
11 pub type KStringCow<'s> = KStringCowBase<'s, crate::backend::DefaultStr>;
12
13 /// A reference to a UTF-8 encoded, immutable string.
14 #[derive(Clone)]
15 #[repr(transparent)]
16 pub struct KStringCowBase<'s, B = crate::backend::DefaultStr> {
17 pub(crate) inner: KStringCowInner<'s, B>,
18 }
19
20 #[derive(Clone)]
21 pub(crate) enum KStringCowInner<'s, B> {
22 Borrowed(&'s str),
23 Owned(KStringBase<B>),
24 }
25
26 impl<'s, B> KStringCowBase<'s, B> {
27 /// Create a new empty `KStringCowBase`.
28 #[inline]
29 #[must_use]
30 pub const fn new() -> Self {
31 Self::from_static("")
32 }
33
34 /// Create a reference to a `'static` data.
35 #[inline]
36 #[must_use]
37 pub const fn from_static(other: &'static str) -> Self {
38 Self {
39 inner: KStringCowInner::Owned(KStringBase::from_static(other)),
40 }
41 }
42 }
43
44 impl<'s, B: crate::backend::HeapStr> KStringCowBase<'s, B> {
45 /// Create an owned `KStringCowBase`.
46 #[inline]
47 #[must_use]
48 pub fn from_boxed(other: BoxedStr) -> Self {
49 Self {
50 inner: KStringCowInner::Owned(KStringBase::from_boxed(other)),
51 }
52 }
53
54 /// Create an owned `KStringCowBase`.
55 #[inline]
56 #[must_use]
57 pub fn from_string(other: StdString) -> Self {
58 Self {
59 inner: KStringCowInner::Owned(KStringBase::from_string(other)),
60 }
61 }
62
63 /// Create a reference to a borrowed data.
64 #[inline]
65 #[must_use]
66 pub fn from_ref(other: &'s str) -> Self {
67 Self {
68 inner: KStringCowInner::Borrowed(other),
69 }
70 }
71
72 /// Get a reference to the `KStringBase`.
73 #[inline]
74 #[must_use]
75 pub fn as_ref(&self) -> KStringRef<'_> {
76 self.inner.as_ref()
77 }
78
79 /// Clone the data into an owned-type.
80 #[inline]
81 #[must_use]
82 pub fn into_owned(self) -> KStringBase<B> {
83 self.inner.into_owned()
84 }
85
86 /// Extracts a string slice containing the entire `KStringCowBase`.
87 #[inline]
88 #[must_use]
89 pub fn as_str(&self) -> &str {
90 self.inner.as_str()
91 }
92
93 /// Convert to a mutable string type, cloning the data if necessary.
94 #[inline]
95 #[must_use]
96 pub fn into_string(self) -> StdString {
97 String::from(self.into_boxed_str())
98 }
99
100 /// Convert to a mutable string type, cloning the data if necessary.
101 #[inline]
102 #[must_use]
103 pub fn into_boxed_str(self) -> BoxedStr {
104 self.inner.into_boxed_str()
105 }
106
107 /// Convert to a Cow str
108 #[inline]
109 #[must_use]
110 pub fn into_cow_str(self) -> Cow<'s, str> {
111 self.inner.into_cow_str()
112 }
113 }
114
115 impl<'s, B: crate::backend::HeapStr> KStringCowInner<'s, B> {
116 #[inline]
117 fn as_ref(&self) -> KStringRef<'_> {
118 match self {
119 Self::Borrowed(s) => KStringRef::from_ref(s),
120 Self::Owned(s) => s.as_ref(),
121 }
122 }
123
124 #[inline]
125 fn into_owned(self) -> KStringBase<B> {
126 match self {
127 Self::Borrowed(s) => KStringBase::from_ref(s),
128 Self::Owned(s) => s,
129 }
130 }
131
132 #[inline]
133 fn as_str(&self) -> &str {
134 match self {
135 Self::Borrowed(s) => s,
136 Self::Owned(s) => s.as_str(),
137 }
138 }
139
140 #[inline]
141 fn into_boxed_str(self) -> BoxedStr {
142 match self {
143 Self::Borrowed(s) => BoxedStr::from(s),
144 Self::Owned(s) => s.into_boxed_str(),
145 }
146 }
147
148 /// Convert to a Cow str
149 #[inline]
150 fn into_cow_str(self) -> Cow<'s, str> {
151 match self {
152 Self::Borrowed(s) => Cow::Borrowed(s),
153 Self::Owned(s) => s.into_cow_str(),
154 }
155 }
156 }
157
158 impl<'s, B: crate::backend::HeapStr> std::ops::Deref for KStringCowBase<'s, B> {
159 type Target = str;
160
161 #[inline]
162 fn deref(&self) -> &str {
163 self.as_str()
164 }
165 }
166
167 impl<'s, B: crate::backend::HeapStr> Eq for KStringCowBase<'s, B> {}
168
169 impl<'s, B: crate::backend::HeapStr> PartialEq<KStringCowBase<'s, B>> for KStringCowBase<'s, B> {
170 #[inline]
171 fn eq(&self, other: &KStringCowBase<'s, B>) -> bool {
172 PartialEq::eq(self.as_str(), other.as_str())
173 }
174 }
175
176 impl<'s, B: crate::backend::HeapStr> PartialEq<str> for KStringCowBase<'s, B> {
177 #[inline]
178 fn eq(&self, other: &str) -> bool {
179 PartialEq::eq(self.as_str(), other)
180 }
181 }
182
183 impl<'s, B: crate::backend::HeapStr> PartialEq<&'s str> for KStringCowBase<'s, B> {
184 #[inline]
185 fn eq(&self, other: &&str) -> bool {
186 PartialEq::eq(self.as_str(), *other)
187 }
188 }
189
190 impl<'s, B: crate::backend::HeapStr> PartialEq<String> for KStringCowBase<'s, B> {
191 #[inline]
192 fn eq(&self, other: &StdString) -> bool {
193 PartialEq::eq(self.as_str(), other.as_str())
194 }
195 }
196
197 impl<'s, B: crate::backend::HeapStr> Ord for KStringCowBase<'s, B> {
198 #[inline]
199 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
200 self.as_str().cmp(other.as_str())
201 }
202 }
203
204 impl<'s, B: crate::backend::HeapStr> PartialOrd for KStringCowBase<'s, B> {
205 #[inline]
206 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
207 self.as_str().partial_cmp(other.as_str())
208 }
209 }
210
211 impl<'s, B: crate::backend::HeapStr> std::hash::Hash for KStringCowBase<'s, B> {
212 #[inline]
213 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
214 self.as_str().hash(state);
215 }
216 }
217
218 impl<'s, B: crate::backend::HeapStr> fmt::Debug for KStringCowBase<'s, B> {
219 #[inline]
220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221 self.as_str().fmt(f)
222 }
223 }
224
225 impl<'s, B: crate::backend::HeapStr> fmt::Display for KStringCowBase<'s, B> {
226 #[inline]
227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228 fmt::Display::fmt(self.as_str(), f)
229 }
230 }
231
232 impl<'s, B: crate::backend::HeapStr> AsRef<str> for KStringCowBase<'s, B> {
233 #[inline]
234 fn as_ref(&self) -> &str {
235 self.as_str()
236 }
237 }
238
239 impl<'s, B: crate::backend::HeapStr> AsRef<[u8]> for KStringCowBase<'s, B> {
240 #[inline]
241 fn as_ref(&self) -> &[u8] {
242 self.as_bytes()
243 }
244 }
245
246 impl<'s, B: crate::backend::HeapStr> AsRef<std::ffi::OsStr> for KStringCowBase<'s, B> {
247 #[inline]
248 fn as_ref(&self) -> &std::ffi::OsStr {
249 (&**self).as_ref()
250 }
251 }
252
253 impl<'s, B: crate::backend::HeapStr> AsRef<std::path::Path> for KStringCowBase<'s, B> {
254 #[inline]
255 fn as_ref(&self) -> &std::path::Path {
256 std::path::Path::new(self)
257 }
258 }
259
260 impl<'s, B: crate::backend::HeapStr> std::borrow::Borrow<str> for KStringCowBase<'s, B> {
261 #[inline]
262 fn borrow(&self) -> &str {
263 self.as_str()
264 }
265 }
266
267 impl<'s, B> Default for KStringCowBase<'s, B> {
268 #[inline]
269 fn default() -> Self {
270 Self::new()
271 }
272 }
273
274 impl<'s, B: crate::backend::HeapStr> From<KStringBase<B>> for KStringCowBase<'s, B> {
275 #[inline]
276 fn from(other: KStringBase<B>) -> Self {
277 let inner = KStringCowInner::Owned(other);
278 Self { inner }
279 }
280 }
281
282 impl<'s, B: crate::backend::HeapStr> From<&'s KStringBase<B>> for KStringCowBase<'s, B> {
283 #[inline]
284 fn from(other: &'s KStringBase<B>) -> Self {
285 let other = other.as_ref();
286 other.into()
287 }
288 }
289
290 impl<'s, B: crate::backend::HeapStr> From<KStringRef<'s>> for KStringCowBase<'s, B> {
291 #[inline]
292 fn from(other: KStringRef<'s>) -> Self {
293 match other.inner {
294 KStringRefInner::Borrowed(s) => Self::from_ref(s),
295 KStringRefInner::Singleton(s) => Self::from_static(s),
296 }
297 }
298 }
299
300 impl<'s, B: crate::backend::HeapStr> From<&'s KStringRef<'s>> for KStringCowBase<'s, B> {
301 #[inline]
302 fn from(other: &'s KStringRef<'s>) -> Self {
303 match other.inner {
304 KStringRefInner::Borrowed(s) => Self::from_ref(s),
305 KStringRefInner::Singleton(s) => Self::from_static(s),
306 }
307 }
308 }
309
310 impl<'s, B: crate::backend::HeapStr> From<StdString> for KStringCowBase<'s, B> {
311 #[inline]
312 fn from(other: StdString) -> Self {
313 Self::from_string(other)
314 }
315 }
316
317 impl<'s, B: crate::backend::HeapStr> From<&'s StdString> for KStringCowBase<'s, B> {
318 #[inline]
319 fn from(other: &'s StdString) -> Self {
320 Self::from_ref(other.as_str())
321 }
322 }
323
324 impl<'s, B: crate::backend::HeapStr> From<BoxedStr> for KStringCowBase<'s, B> {
325 #[inline]
326 fn from(other: BoxedStr) -> Self {
327 // Since the memory is already allocated, don't bother moving it into a FixedString
328 Self::from_boxed(other)
329 }
330 }
331
332 impl<'s, B: crate::backend::HeapStr> From<&'s BoxedStr> for KStringCowBase<'s, B> {
333 #[inline]
334 fn from(other: &'s BoxedStr) -> Self {
335 Self::from_ref(other)
336 }
337 }
338
339 impl<'s, B: crate::backend::HeapStr> From<&'s str> for KStringCowBase<'s, B> {
340 #[inline]
341 fn from(other: &'s str) -> Self {
342 Self::from_ref(other)
343 }
344 }
345
346 impl<B: crate::backend::HeapStr> std::str::FromStr for KStringCowBase<'_, B> {
347 type Err = std::convert::Infallible;
348 #[inline]
349 fn from_str(s: &str) -> Result<Self, Self::Err> {
350 Ok(Self::from_string(s.into()))
351 }
352 }
353
354 #[cfg(feature = "serde")]
355 impl<'s, B: crate::backend::HeapStr> serde::Serialize for KStringCowBase<'s, B> {
356 #[inline]
357 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
358 where
359 S: serde::Serializer,
360 {
361 serializer.serialize_str(self.as_str())
362 }
363 }
364
365 #[cfg(feature = "serde")]
366 impl<'de, 's, B: crate::backend::HeapStr> serde::Deserialize<'de> for KStringCowBase<'s, B> {
367 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
368 where
369 D: serde::Deserializer<'de>,
370 {
371 KStringBase::deserialize(deserializer).map(|s| s.into())
372 }
373 }
374
375 #[cfg(test)]
376 mod test {
377 use super::*;
378
379 #[test]
380 fn test_size() {
381 println!("KStringCow: {}", std::mem::size_of::<KStringCow<'static>>());
382 }
383 }