1use core::fmt::Debug;
4use core::ops::Deref;
5
6#[cfg(feature = "alloc")]
7use alloc::{
8 boxed::Box,
9 string::String,
10};
11
12use crate::{TinyString, TinyVec};
13
14pub enum Cow<'borrow, const N: usize> {
38 Borrowed(&'borrow str),
39 Owned(TinyString<N>),
40}
41
42impl<'borrow, const N: usize> Cow<'borrow, N> {
43 pub fn to_owned(&mut self) {
45 if let Cow::Borrowed(b) = self {
46 unsafe {
47 let utf8 = TinyVec::from_slice_copied(b.as_bytes());
48 let tv = TinyString::<N>::from_utf8_unchecked(utf8);
49 *self = Cow::Owned(tv)
50 }
51 }
52 }
53
54 pub fn into_owned(mut self) -> TinyString<N> {
56 self.to_owned();
57 match self {
58 Cow::Owned(w) => w,
59 Cow::Borrowed(_) => unreachable!("Self::to_owned must've turn self into an Owned variant"),
60 }
61 }
62
63 pub fn to_mut(&mut self) -> &mut TinyString<N> {
69 self.to_owned();
70 match self {
71 Cow::Owned(w) => w,
72 Cow::Borrowed(_) => unreachable!("Self::to_owned must've turn self into an Owned variant"),
73 }
74 }
75
76 pub const fn is_borrowed(&self) -> bool {
78 matches!(self, Cow::Borrowed(_))
79 }
80
81 pub const fn is_owned(&self) -> bool {
83 matches!(self, Cow::Owned(_))
84 }
85
86 pub const fn lives_on_stack(&self) -> bool {
91 match self {
92 Cow::Borrowed(_) => true,
93 Cow::Owned(v) => v.lives_on_stack(),
94 }
95 }
96
97 pub const fn as_str(&self) -> &str {
99 match self {
100 Cow::Borrowed(items) => items,
101 Cow::Owned(tiny_string) => tiny_string.as_str()
102 }
103 }
104}
105
106impl<'borrow, const N: usize> Deref for Cow<'borrow, N> {
107 type Target = str;
108
109 fn deref(&self) -> &Self::Target {
110 self.as_str()
111 }
112}
113
114impl<'borrow, const N: usize> From<&'borrow str> for Cow<'borrow, N> {
115 fn from(value: &'borrow str) -> Self {
116 Self::Borrowed(value)
117 }
118}
119
120impl<'borrow, 'b2, const N: usize> From<&'b2 Cow<'borrow, N>> for Cow<'b2, N> {
121 fn from(value: &'b2 Cow<'borrow, N>) -> Self {
122 Cow::Borrowed(value.as_str())
123 }
124}
125
126impl<'borrow, const N: usize> From<TinyString<N>> for Cow<'borrow, N> {
127 fn from(value: TinyString<N>) -> Self {
128 Self::Owned(value)
129 }
130}
131
132impl<'borrow, const N: usize> From<&'borrow TinyString<N>> for Cow<'borrow, N> {
133 fn from(value: &'borrow TinyString<N>) -> Self {
134 Self::Borrowed(value)
135 }
136}
137
138#[cfg(feature = "alloc")]
139impl<'borrow, const N: usize> From<String> for Cow<'borrow, N> {
140 fn from(value: String) -> Self {
141 Self::Owned(TinyString::from(value))
142 }
143}
144
145#[cfg(feature = "alloc")]
146impl<'borrow, const N: usize> From<Box<str>> for Cow<'borrow, N> {
147 fn from(value: Box<str>) -> Self {
148 Self::Owned(TinyString::from(value))
149 }
150}
151
152impl<'borrow, const N: usize> Debug for Cow<'borrow, N> {
153 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
154 match self {
155 Self::Borrowed(arg0) => f.debug_tuple("Borrowed").field(arg0).finish(),
156 Self::Owned(arg0) => f.debug_tuple("Owned").field(arg0).finish(),
157 }
158 }
159}
160
161impl<'borrow, const N: usize> PartialEq for Cow<'borrow, N> {
162 fn eq(&self, other: &Self) -> bool {
163 match (self, other) {
164 (Self::Borrowed(l0), Self::Borrowed(r0)) => l0 == r0,
165 (Self::Owned(l0), Self::Owned(r0)) => l0 == r0,
166 _ => false,
167 }
168 }
169}
170
171impl<'borrow, const N: usize> PartialEq<str> for Cow<'borrow, N> {
172 fn eq(&self, other: &str) -> bool {
173 self.as_str() == other
174 }
175}
176
177impl<'borrow, const N: usize> PartialEq<Cow<'borrow, N>> for str {
178 fn eq(&self, other: &Cow<'borrow, N>) -> bool {
179 self == other.as_str()
180 }
181}
182
183impl<'borrow, const N: usize> Clone for Cow<'borrow, N> {
184 fn clone(&self) -> Self {
185 match self {
186 Self::Borrowed(arg0) => Self::Borrowed(arg0),
187 Self::Owned(arg0) => Self::Owned(arg0.clone()),
188 }
189 }
190}
191
192impl<'borrow, const N: usize> Default for Cow<'borrow, N> {
193 fn default() -> Self {
194 Self::Borrowed("")
195 }
196}