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 | |