| 1 | /*! |
| 2 | This module re-exports a "dumb" version of `std::borrow::Cow`. |
| 3 | |
| 4 | It doesn't have any of the generic goodness and doesn't support dynamically |
| 5 | sized types. It's just either a `T` or a `&T`. |
| 6 | |
| 7 | We have pretty simplistic needs, and we use this simpler type that works |
| 8 | in core-only mode. |
| 9 | */ |
| 10 | |
| 11 | #[derive (Clone, Debug)] |
| 12 | pub(crate) enum DumbCow<'a, T> { |
| 13 | Owned(T), |
| 14 | Borrowed(&'a T), |
| 15 | } |
| 16 | |
| 17 | impl<'a, T> DumbCow<'a, T> { |
| 18 | pub(crate) fn borrowed(&self) -> DumbCow<'_, T> { |
| 19 | match *self { |
| 20 | DumbCow::Owned(ref this: &T) => DumbCow::Borrowed(this), |
| 21 | DumbCow::Borrowed(ref this: &&T) => DumbCow::Borrowed(this), |
| 22 | } |
| 23 | } |
| 24 | } |
| 25 | |
| 26 | impl<'a, T> core::ops::Deref for DumbCow<'a, T> { |
| 27 | type Target = T; |
| 28 | fn deref(&self) -> &T { |
| 29 | match *self { |
| 30 | DumbCow::Owned(ref t: &T) => t, |
| 31 | DumbCow::Borrowed(t: &T) => t, |
| 32 | } |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | impl<'a, T: core::fmt::Display> core::fmt::Display for DumbCow<'a, T> { |
| 37 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { |
| 38 | core::fmt::Display::fmt(self:core::ops::Deref::deref(self), f) |
| 39 | } |
| 40 | } |
| 41 | |
| 42 | /// A `Cow`, but can be used in core-only mode. |
| 43 | /// |
| 44 | /// In core-only, the `Owned` variant doesn't exist. |
| 45 | #[derive (Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)] |
| 46 | pub(crate) enum StringCow<'a> { |
| 47 | #[cfg (feature = "alloc" )] |
| 48 | Owned(alloc::string::String), |
| 49 | Borrowed(&'a str), |
| 50 | } |
| 51 | |
| 52 | impl<'a> StringCow<'a> { |
| 53 | /// Returns this `String` or `&str` as a `&str`. |
| 54 | /// |
| 55 | /// Like `std::borrow::Cow`, the lifetime of the string slice returned |
| 56 | /// is tied to `StringCow`, and _not_ the original lifetime of the string |
| 57 | /// slice. |
| 58 | pub(crate) fn as_str<'s>(&'s self) -> &'s str { |
| 59 | match *self { |
| 60 | #[cfg (feature = "alloc" )] |
| 61 | StringCow::Owned(ref s) => s, |
| 62 | StringCow::Borrowed(s) => s, |
| 63 | } |
| 64 | } |
| 65 | |
| 66 | /// Converts this cow into an "owned" variant, copying if necessary. |
| 67 | /// |
| 68 | /// If this cow is already an "owned" variant, then this is a no-op. |
| 69 | #[cfg (feature = "alloc" )] |
| 70 | pub(crate) fn into_owned(self) -> StringCow<'static> { |
| 71 | use alloc::string::ToString; |
| 72 | |
| 73 | match self { |
| 74 | StringCow::Owned(string) => StringCow::Owned(string), |
| 75 | StringCow::Borrowed(string) => { |
| 76 | StringCow::Owned(string.to_string()) |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | impl<'a> core::ops::Deref for StringCow<'a> { |
| 83 | type Target = str; |
| 84 | fn deref(&self) -> &str { |
| 85 | self.as_str() |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | impl<'a> core::fmt::Display for StringCow<'a> { |
| 90 | fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { |
| 91 | core::fmt::Display::fmt(self.as_str(), f) |
| 92 | } |
| 93 | } |
| 94 | |
| 95 | #[cfg (feature = "alloc" )] |
| 96 | impl From<alloc::string::String> for StringCow<'static> { |
| 97 | fn from(string: alloc::string::String) -> StringCow<'static> { |
| 98 | StringCow::Owned(string) |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | impl<'a> From<&'a str> for StringCow<'a> { |
| 103 | fn from(string: &'a str) -> StringCow<'a> { |
| 104 | StringCow::Borrowed(string) |
| 105 | } |
| 106 | } |
| 107 | |