alloc/
bstr.rs

1//! The `ByteStr` and `ByteString` types and trait implementations.
2
3// This could be more fine-grained.
4#![cfg(not(no_global_oom_handling))]
5
6use core::borrow::{Borrow, BorrowMut};
7#[unstable(feature = "bstr", issue = "134915")]
8pub use core::bstr::ByteStr;
9use core::bstr::{impl_partial_eq, impl_partial_eq_n, impl_partial_eq_ord};
10use core::cmp::Ordering;
11use core::ops::{
12    Deref, DerefMut, DerefPure, Index, IndexMut, Range, RangeFrom, RangeFull, RangeInclusive,
13    RangeTo, RangeToInclusive,
14};
15use core::str::FromStr;
16use core::{fmt, hash};
17
18use crate::borrow::{Cow, ToOwned};
19use crate::boxed::Box;
20#[cfg(not(no_rc))]
21use crate::rc::Rc;
22use crate::string::String;
23#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
24use crate::sync::Arc;
25use crate::vec::Vec;
26
27/// A wrapper for `Vec<u8>` representing a human-readable string that's conventionally, but not
28/// always, UTF-8.
29///
30/// Unlike `String`, this type permits non-UTF-8 contents, making it suitable for user input,
31/// non-native filenames (as `Path` only supports native filenames), and other applications that
32/// need to round-trip whatever data the user provides.
33///
34/// A `ByteString` owns its contents and can grow and shrink, like a `Vec` or `String`. For a
35/// borrowed byte string, see [`ByteStr`](../../std/bstr/struct.ByteStr.html).
36///
37/// `ByteString` implements `Deref` to `&Vec<u8>`, so all methods available on `&Vec<u8>` are
38/// available on `ByteString`. Similarly, `ByteString` implements `DerefMut` to `&mut Vec<u8>`,
39/// so you can modify a `ByteString` using any method available on `&mut Vec<u8>`.
40///
41/// The `Debug` and `Display` implementations for `ByteString` are the same as those for `ByteStr`,
42/// showing invalid UTF-8 as hex escapes or the Unicode replacement character, respectively.
43#[unstable(feature = "bstr", issue = "134915")]
44#[repr(transparent)]
45#[derive(Clone)]
46#[doc(alias = "BString")]
47pub struct ByteString(pub Vec<u8>);
48
49impl ByteString {
50    #[inline]
51    pub(crate) fn as_bytes(&self) -> &[u8] {
52        &self.0
53    }
54
55    #[inline]
56    pub(crate) fn as_bytestr(&self) -> &ByteStr {
57        ByteStr::new(&self.0)
58    }
59
60    #[inline]
61    pub(crate) fn as_mut_bytestr(&mut self) -> &mut ByteStr {
62        ByteStr::from_bytes_mut(&mut self.0)
63    }
64}
65
66#[unstable(feature = "bstr", issue = "134915")]
67impl Deref for ByteString {
68    type Target = Vec<u8>;
69
70    #[inline]
71    fn deref(&self) -> &Self::Target {
72        &self.0
73    }
74}
75
76#[unstable(feature = "bstr", issue = "134915")]
77impl DerefMut for ByteString {
78    #[inline]
79    fn deref_mut(&mut self) -> &mut Self::Target {
80        &mut self.0
81    }
82}
83
84#[unstable(feature = "deref_pure_trait", issue = "87121")]
85unsafe impl DerefPure for ByteString {}
86
87#[unstable(feature = "bstr", issue = "134915")]
88impl fmt::Debug for ByteString {
89    #[inline]
90    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91        fmt::Debug::fmt(self.as_bytestr(), f)
92    }
93}
94
95#[unstable(feature = "bstr", issue = "134915")]
96impl fmt::Display for ByteString {
97    #[inline]
98    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99        fmt::Display::fmt(self.as_bytestr(), f)
100    }
101}
102
103#[unstable(feature = "bstr", issue = "134915")]
104impl AsRef<[u8]> for ByteString {
105    #[inline]
106    fn as_ref(&self) -> &[u8] {
107        &self.0
108    }
109}
110
111#[unstable(feature = "bstr", issue = "134915")]
112impl AsRef<ByteStr> for ByteString {
113    #[inline]
114    fn as_ref(&self) -> &ByteStr {
115        self.as_bytestr()
116    }
117}
118
119#[unstable(feature = "bstr", issue = "134915")]
120impl AsMut<[u8]> for ByteString {
121    #[inline]
122    fn as_mut(&mut self) -> &mut [u8] {
123        &mut self.0
124    }
125}
126
127#[unstable(feature = "bstr", issue = "134915")]
128impl AsMut<ByteStr> for ByteString {
129    #[inline]
130    fn as_mut(&mut self) -> &mut ByteStr {
131        self.as_mut_bytestr()
132    }
133}
134
135#[unstable(feature = "bstr", issue = "134915")]
136impl Borrow<[u8]> for ByteString {
137    #[inline]
138    fn borrow(&self) -> &[u8] {
139        &self.0
140    }
141}
142
143#[unstable(feature = "bstr", issue = "134915")]
144impl Borrow<ByteStr> for ByteString {
145    #[inline]
146    fn borrow(&self) -> &ByteStr {
147        self.as_bytestr()
148    }
149}
150
151// `impl Borrow<ByteStr> for Vec<u8>` omitted to avoid inference failures
152// `impl Borrow<ByteStr> for String` omitted to avoid inference failures
153
154#[unstable(feature = "bstr", issue = "134915")]
155impl BorrowMut<[u8]> for ByteString {
156    #[inline]
157    fn borrow_mut(&mut self) -> &mut [u8] {
158        &mut self.0
159    }
160}
161
162#[unstable(feature = "bstr", issue = "134915")]
163impl BorrowMut<ByteStr> for ByteString {
164    #[inline]
165    fn borrow_mut(&mut self) -> &mut ByteStr {
166        self.as_mut_bytestr()
167    }
168}
169
170// `impl BorrowMut<ByteStr> for Vec<u8>` omitted to avoid inference failures
171
172#[unstable(feature = "bstr", issue = "134915")]
173impl Default for ByteString {
174    fn default() -> Self {
175        ByteString(Vec::new())
176    }
177}
178
179// Omitted due to inference failures
180//
181// #[unstable(feature = "bstr", issue = "134915")]
182// impl<'a, const N: usize> From<&'a [u8; N]> for ByteString {
183//     #[inline]
184//     fn from(s: &'a [u8; N]) -> Self {
185//         ByteString(s.as_slice().to_vec())
186//     }
187// }
188//
189// #[unstable(feature = "bstr", issue = "134915")]
190// impl<const N: usize> From<[u8; N]> for ByteString {
191//     #[inline]
192//     fn from(s: [u8; N]) -> Self {
193//         ByteString(s.as_slice().to_vec())
194//     }
195// }
196//
197// #[unstable(feature = "bstr", issue = "134915")]
198// impl<'a> From<&'a [u8]> for ByteString {
199//     #[inline]
200//     fn from(s: &'a [u8]) -> Self {
201//         ByteString(s.to_vec())
202//     }
203// }
204//
205// #[unstable(feature = "bstr", issue = "134915")]
206// impl From<Vec<u8>> for ByteString {
207//     #[inline]
208//     fn from(s: Vec<u8>) -> Self {
209//         ByteString(s)
210//     }
211// }
212
213#[unstable(feature = "bstr", issue = "134915")]
214impl From<ByteString> for Vec<u8> {
215    #[inline]
216    fn from(s: ByteString) -> Self {
217        s.0
218    }
219}
220
221// Omitted due to inference failures
222//
223// #[unstable(feature = "bstr", issue = "134915")]
224// impl<'a> From<&'a str> for ByteString {
225//     #[inline]
226//     fn from(s: &'a str) -> Self {
227//         ByteString(s.as_bytes().to_vec())
228//     }
229// }
230//
231// #[unstable(feature = "bstr", issue = "134915")]
232// impl From<String> for ByteString {
233//     #[inline]
234//     fn from(s: String) -> Self {
235//         ByteString(s.into_bytes())
236//     }
237// }
238
239#[unstable(feature = "bstr", issue = "134915")]
240impl<'a> From<&'a ByteStr> for ByteString {
241    #[inline]
242    fn from(s: &'a ByteStr) -> Self {
243        ByteString(s.0.to_vec())
244    }
245}
246
247#[unstable(feature = "bstr", issue = "134915")]
248impl<'a> From<ByteString> for Cow<'a, ByteStr> {
249    #[inline]
250    fn from(s: ByteString) -> Self {
251        Cow::Owned(s)
252    }
253}
254
255#[unstable(feature = "bstr", issue = "134915")]
256impl<'a> From<&'a ByteString> for Cow<'a, ByteStr> {
257    #[inline]
258    fn from(s: &'a ByteString) -> Self {
259        Cow::Borrowed(s.as_bytestr())
260    }
261}
262
263#[unstable(feature = "bstr", issue = "134915")]
264impl FromIterator<char> for ByteString {
265    #[inline]
266    fn from_iter<T: IntoIterator<Item = char>>(iter: T) -> Self {
267        ByteString(iter.into_iter().collect::<String>().into_bytes())
268    }
269}
270
271#[unstable(feature = "bstr", issue = "134915")]
272impl FromIterator<u8> for ByteString {
273    #[inline]
274    fn from_iter<T: IntoIterator<Item = u8>>(iter: T) -> Self {
275        ByteString(iter.into_iter().collect())
276    }
277}
278
279#[unstable(feature = "bstr", issue = "134915")]
280impl<'a> FromIterator<&'a str> for ByteString {
281    #[inline]
282    fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
283        ByteString(iter.into_iter().collect::<String>().into_bytes())
284    }
285}
286
287#[unstable(feature = "bstr", issue = "134915")]
288impl<'a> FromIterator<&'a [u8]> for ByteString {
289    #[inline]
290    fn from_iter<T: IntoIterator<Item = &'a [u8]>>(iter: T) -> Self {
291        let mut buf = Vec::new();
292        for b in iter {
293            buf.extend_from_slice(b);
294        }
295        ByteString(buf)
296    }
297}
298
299#[unstable(feature = "bstr", issue = "134915")]
300impl<'a> FromIterator<&'a ByteStr> for ByteString {
301    #[inline]
302    fn from_iter<T: IntoIterator<Item = &'a ByteStr>>(iter: T) -> Self {
303        let mut buf = Vec::new();
304        for b in iter {
305            buf.extend_from_slice(&b.0);
306        }
307        ByteString(buf)
308    }
309}
310
311#[unstable(feature = "bstr", issue = "134915")]
312impl FromIterator<ByteString> for ByteString {
313    #[inline]
314    fn from_iter<T: IntoIterator<Item = ByteString>>(iter: T) -> Self {
315        let mut buf = Vec::new();
316        for mut b in iter {
317            buf.append(&mut b.0);
318        }
319        ByteString(buf)
320    }
321}
322
323#[unstable(feature = "bstr", issue = "134915")]
324impl FromStr for ByteString {
325    type Err = core::convert::Infallible;
326
327    #[inline]
328    fn from_str(s: &str) -> Result<Self, Self::Err> {
329        Ok(ByteString(s.as_bytes().to_vec()))
330    }
331}
332
333#[unstable(feature = "bstr", issue = "134915")]
334impl Index<usize> for ByteString {
335    type Output = u8;
336
337    #[inline]
338    fn index(&self, idx: usize) -> &u8 {
339        &self.0[idx]
340    }
341}
342
343#[unstable(feature = "bstr", issue = "134915")]
344impl Index<RangeFull> for ByteString {
345    type Output = ByteStr;
346
347    #[inline]
348    fn index(&self, _: RangeFull) -> &ByteStr {
349        self.as_bytestr()
350    }
351}
352
353#[unstable(feature = "bstr", issue = "134915")]
354impl Index<Range<usize>> for ByteString {
355    type Output = ByteStr;
356
357    #[inline]
358    fn index(&self, r: Range<usize>) -> &ByteStr {
359        ByteStr::from_bytes(&self.0[r])
360    }
361}
362
363#[unstable(feature = "bstr", issue = "134915")]
364impl Index<RangeInclusive<usize>> for ByteString {
365    type Output = ByteStr;
366
367    #[inline]
368    fn index(&self, r: RangeInclusive<usize>) -> &ByteStr {
369        ByteStr::from_bytes(&self.0[r])
370    }
371}
372
373#[unstable(feature = "bstr", issue = "134915")]
374impl Index<RangeFrom<usize>> for ByteString {
375    type Output = ByteStr;
376
377    #[inline]
378    fn index(&self, r: RangeFrom<usize>) -> &ByteStr {
379        ByteStr::from_bytes(&self.0[r])
380    }
381}
382
383#[unstable(feature = "bstr", issue = "134915")]
384impl Index<RangeTo<usize>> for ByteString {
385    type Output = ByteStr;
386
387    #[inline]
388    fn index(&self, r: RangeTo<usize>) -> &ByteStr {
389        ByteStr::from_bytes(&self.0[r])
390    }
391}
392
393#[unstable(feature = "bstr", issue = "134915")]
394impl Index<RangeToInclusive<usize>> for ByteString {
395    type Output = ByteStr;
396
397    #[inline]
398    fn index(&self, r: RangeToInclusive<usize>) -> &ByteStr {
399        ByteStr::from_bytes(&self.0[r])
400    }
401}
402
403#[unstable(feature = "bstr", issue = "134915")]
404impl IndexMut<usize> for ByteString {
405    #[inline]
406    fn index_mut(&mut self, idx: usize) -> &mut u8 {
407        &mut self.0[idx]
408    }
409}
410
411#[unstable(feature = "bstr", issue = "134915")]
412impl IndexMut<RangeFull> for ByteString {
413    #[inline]
414    fn index_mut(&mut self, _: RangeFull) -> &mut ByteStr {
415        self.as_mut_bytestr()
416    }
417}
418
419#[unstable(feature = "bstr", issue = "134915")]
420impl IndexMut<Range<usize>> for ByteString {
421    #[inline]
422    fn index_mut(&mut self, r: Range<usize>) -> &mut ByteStr {
423        ByteStr::from_bytes_mut(&mut self.0[r])
424    }
425}
426
427#[unstable(feature = "bstr", issue = "134915")]
428impl IndexMut<RangeInclusive<usize>> for ByteString {
429    #[inline]
430    fn index_mut(&mut self, r: RangeInclusive<usize>) -> &mut ByteStr {
431        ByteStr::from_bytes_mut(&mut self.0[r])
432    }
433}
434
435#[unstable(feature = "bstr", issue = "134915")]
436impl IndexMut<RangeFrom<usize>> for ByteString {
437    #[inline]
438    fn index_mut(&mut self, r: RangeFrom<usize>) -> &mut ByteStr {
439        ByteStr::from_bytes_mut(&mut self.0[r])
440    }
441}
442
443#[unstable(feature = "bstr", issue = "134915")]
444impl IndexMut<RangeTo<usize>> for ByteString {
445    #[inline]
446    fn index_mut(&mut self, r: RangeTo<usize>) -> &mut ByteStr {
447        ByteStr::from_bytes_mut(&mut self.0[r])
448    }
449}
450
451#[unstable(feature = "bstr", issue = "134915")]
452impl IndexMut<RangeToInclusive<usize>> for ByteString {
453    #[inline]
454    fn index_mut(&mut self, r: RangeToInclusive<usize>) -> &mut ByteStr {
455        ByteStr::from_bytes_mut(&mut self.0[r])
456    }
457}
458
459#[unstable(feature = "bstr", issue = "134915")]
460impl hash::Hash for ByteString {
461    #[inline]
462    fn hash<H: hash::Hasher>(&self, state: &mut H) {
463        self.0.hash(state);
464    }
465}
466
467#[unstable(feature = "bstr", issue = "134915")]
468impl Eq for ByteString {}
469
470#[unstable(feature = "bstr", issue = "134915")]
471impl PartialEq for ByteString {
472    #[inline]
473    fn eq(&self, other: &ByteString) -> bool {
474        self.0 == other.0
475    }
476}
477
478macro_rules! impl_partial_eq_ord_cow {
479    ($lhs:ty, $rhs:ty) => {
480        #[allow(unused_lifetimes)]
481        #[unstable(feature = "bstr", issue = "134915")]
482        impl<'a> PartialEq<$rhs> for $lhs {
483            #[inline]
484            fn eq(&self, other: &$rhs) -> bool {
485                let other: &[u8] = (&**other).as_ref();
486                PartialEq::eq(self.as_bytes(), other)
487            }
488        }
489
490        #[allow(unused_lifetimes)]
491        #[unstable(feature = "bstr", issue = "134915")]
492        impl<'a> PartialEq<$lhs> for $rhs {
493            #[inline]
494            fn eq(&self, other: &$lhs) -> bool {
495                let this: &[u8] = (&**self).as_ref();
496                PartialEq::eq(this, other.as_bytes())
497            }
498        }
499
500        #[allow(unused_lifetimes)]
501        #[unstable(feature = "bstr", issue = "134915")]
502        impl<'a> PartialOrd<$rhs> for $lhs {
503            #[inline]
504            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
505                let other: &[u8] = (&**other).as_ref();
506                PartialOrd::partial_cmp(self.as_bytes(), other)
507            }
508        }
509
510        #[allow(unused_lifetimes)]
511        #[unstable(feature = "bstr", issue = "134915")]
512        impl<'a> PartialOrd<$lhs> for $rhs {
513            #[inline]
514            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
515                let this: &[u8] = (&**self).as_ref();
516                PartialOrd::partial_cmp(this, other.as_bytes())
517            }
518        }
519    };
520}
521
522// PartialOrd with `Vec<u8>` omitted to avoid inference failures
523impl_partial_eq!(ByteString, Vec<u8>);
524// PartialOrd with `[u8]` omitted to avoid inference failures
525impl_partial_eq!(ByteString, [u8]);
526// PartialOrd with `&[u8]` omitted to avoid inference failures
527impl_partial_eq!(ByteString, &[u8]);
528// PartialOrd with `String` omitted to avoid inference failures
529impl_partial_eq!(ByteString, String);
530// PartialOrd with `str` omitted to avoid inference failures
531impl_partial_eq!(ByteString, str);
532// PartialOrd with `&str` omitted to avoid inference failures
533impl_partial_eq!(ByteString, &str);
534impl_partial_eq_ord!(ByteString, ByteStr);
535impl_partial_eq_ord!(ByteString, &ByteStr);
536// PartialOrd with `[u8; N]` omitted to avoid inference failures
537impl_partial_eq_n!(ByteString, [u8; N]);
538// PartialOrd with `&[u8; N]` omitted to avoid inference failures
539impl_partial_eq_n!(ByteString, &[u8; N]);
540impl_partial_eq_ord_cow!(ByteString, Cow<'_, ByteStr>);
541impl_partial_eq_ord_cow!(ByteString, Cow<'_, str>);
542impl_partial_eq_ord_cow!(ByteString, Cow<'_, [u8]>);
543
544#[unstable(feature = "bstr", issue = "134915")]
545impl Ord for ByteString {
546    #[inline]
547    fn cmp(&self, other: &ByteString) -> Ordering {
548        Ord::cmp(&self.0, &other.0)
549    }
550}
551
552#[unstable(feature = "bstr", issue = "134915")]
553impl PartialOrd for ByteString {
554    #[inline]
555    fn partial_cmp(&self, other: &ByteString) -> Option<Ordering> {
556        PartialOrd::partial_cmp(&self.0, &other.0)
557    }
558}
559
560#[unstable(feature = "bstr", issue = "134915")]
561impl ToOwned for ByteStr {
562    type Owned = ByteString;
563
564    #[inline]
565    fn to_owned(&self) -> ByteString {
566        ByteString(self.0.to_vec())
567    }
568}
569
570#[unstable(feature = "bstr", issue = "134915")]
571impl TryFrom<ByteString> for String {
572    type Error = crate::string::FromUtf8Error;
573
574    #[inline]
575    fn try_from(s: ByteString) -> Result<Self, Self::Error> {
576        String::from_utf8(s.0)
577    }
578}
579
580#[unstable(feature = "bstr", issue = "134915")]
581impl<'a> TryFrom<&'a ByteString> for &'a str {
582    type Error = crate::str::Utf8Error;
583
584    #[inline]
585    fn try_from(s: &'a ByteString) -> Result<Self, Self::Error> {
586        crate::str::from_utf8(s.0.as_slice())
587    }
588}
589
590// Additional impls for `ByteStr` that require types from `alloc`:
591
592#[unstable(feature = "bstr", issue = "134915")]
593impl Clone for Box<ByteStr> {
594    #[inline]
595    fn clone(&self) -> Self {
596        Self::from(Box::<[u8]>::from(&self.0))
597    }
598}
599
600#[unstable(feature = "bstr", issue = "134915")]
601impl<'a> From<&'a ByteStr> for Cow<'a, ByteStr> {
602    #[inline]
603    fn from(s: &'a ByteStr) -> Self {
604        Cow::Borrowed(s)
605    }
606}
607
608#[unstable(feature = "bstr", issue = "134915")]
609impl From<Box<[u8]>> for Box<ByteStr> {
610    #[inline]
611    fn from(s: Box<[u8]>) -> Box<ByteStr> {
612        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
613        unsafe { Box::from_raw(Box::into_raw(s) as _) }
614    }
615}
616
617#[unstable(feature = "bstr", issue = "134915")]
618impl From<Box<ByteStr>> for Box<[u8]> {
619    #[inline]
620    fn from(s: Box<ByteStr>) -> Box<[u8]> {
621        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
622        unsafe { Box::from_raw(Box::into_raw(s) as _) }
623    }
624}
625
626#[unstable(feature = "bstr", issue = "134915")]
627#[cfg(not(no_rc))]
628impl From<Rc<[u8]>> for Rc<ByteStr> {
629    #[inline]
630    fn from(s: Rc<[u8]>) -> Rc<ByteStr> {
631        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
632        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
633    }
634}
635
636#[unstable(feature = "bstr", issue = "134915")]
637#[cfg(not(no_rc))]
638impl From<Rc<ByteStr>> for Rc<[u8]> {
639    #[inline]
640    fn from(s: Rc<ByteStr>) -> Rc<[u8]> {
641        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
642        unsafe { Rc::from_raw(Rc::into_raw(s) as _) }
643    }
644}
645
646#[unstable(feature = "bstr", issue = "134915")]
647#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
648impl From<Arc<[u8]>> for Arc<ByteStr> {
649    #[inline]
650    fn from(s: Arc<[u8]>) -> Arc<ByteStr> {
651        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
652        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
653    }
654}
655
656#[unstable(feature = "bstr", issue = "134915")]
657#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
658impl From<Arc<ByteStr>> for Arc<[u8]> {
659    #[inline]
660    fn from(s: Arc<ByteStr>) -> Arc<[u8]> {
661        // SAFETY: `ByteStr` is a transparent wrapper around `[u8]`.
662        unsafe { Arc::from_raw(Arc::into_raw(s) as _) }
663    }
664}
665
666// PartialOrd with `Vec<u8>` omitted to avoid inference failures
667impl_partial_eq!(ByteStr, Vec<u8>);
668// PartialOrd with `String` omitted to avoid inference failures
669impl_partial_eq!(ByteStr, String);
670impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, ByteStr>);
671impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, str>);
672impl_partial_eq_ord_cow!(&'a ByteStr, Cow<'a, [u8]>);
673
674#[unstable(feature = "bstr", issue = "134915")]
675impl<'a> TryFrom<&'a ByteStr> for String {
676    type Error = core::str::Utf8Error;
677
678    #[inline]
679    fn try_from(s: &'a ByteStr) -> Result<Self, Self::Error> {
680        Ok(core::str::from_utf8(&s.0)?.into())
681    }
682}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy