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 pub const fn as_bytes(&self) -> &[u8] {
107 match self {
108 Cow::Borrowed(b) => b.as_bytes(),
109 Cow::Owned(s) => s.as_bytes(),
110 }
111 }
112}
113
114impl<'borrow, const N: usize> Deref for Cow<'borrow, N> {
115 type Target = str;
116
117 fn deref(&self) -> &Self::Target {
118 self.as_str()
119 }
120}
121
122impl<'borrow, const N: usize> From<&'borrow str> for Cow<'borrow, N> {
123 fn from(value: &'borrow str) -> Self {
124 Self::Borrowed(value)
125 }
126}
127
128impl<'borrow, 'b2, const N: usize> From<&'b2 Cow<'borrow, N>> for Cow<'b2, N> {
129 fn from(value: &'b2 Cow<'borrow, N>) -> Self {
130 Cow::Borrowed(value.as_str())
131 }
132}
133
134impl<'borrow, const N: usize> From<TinyString<N>> for Cow<'borrow, N> {
135 fn from(value: TinyString<N>) -> Self {
136 Self::Owned(value)
137 }
138}
139
140impl<'borrow, const N: usize> From<&'borrow TinyString<N>> for Cow<'borrow, N> {
141 fn from(value: &'borrow TinyString<N>) -> Self {
142 Self::Borrowed(value)
143 }
144}
145
146#[cfg(feature = "alloc")]
147impl<'borrow, const N: usize> From<String> for Cow<'borrow, N> {
148 fn from(value: String) -> Self {
149 Self::Owned(TinyString::from(value))
150 }
151}
152
153#[cfg(feature = "alloc")]
154impl<'borrow, const N: usize> From<Box<str>> for Cow<'borrow, N> {
155 fn from(value: Box<str>) -> Self {
156 Self::Owned(TinyString::from(value))
157 }
158}
159
160impl<'borrow, const N: usize> Debug for Cow<'borrow, N> {
161 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
162 match self {
163 Self::Borrowed(arg0) => f.debug_tuple("Borrowed").field(arg0).finish(),
164 Self::Owned(arg0) => f.debug_tuple("Owned").field(arg0).finish(),
165 }
166 }
167}
168
169impl<'borrow, const N: usize> PartialEq for Cow<'borrow, N> {
170 fn eq(&self, other: &Self) -> bool {
171 match (self, other) {
172 (Self::Borrowed(l0), Self::Borrowed(r0)) => l0 == r0,
173 (Self::Owned(l0), Self::Owned(r0)) => l0 == r0,
174 _ => false,
175 }
176 }
177}
178
179impl<'borrow, const N: usize> PartialEq<str> for Cow<'borrow, N> {
180 fn eq(&self, other: &str) -> bool {
181 self.as_str() == other
182 }
183}
184
185impl<'borrow, const N: usize> PartialEq<Cow<'borrow, N>> for str {
186 fn eq(&self, other: &Cow<'borrow, N>) -> bool {
187 self == other.as_str()
188 }
189}
190
191impl<'borrow, const N: usize> Clone for Cow<'borrow, N> {
192 fn clone(&self) -> Self {
193 match self {
194 Self::Borrowed(arg0) => Self::Borrowed(arg0),
195 Self::Owned(arg0) => Self::Owned(arg0.clone()),
196 }
197 }
198}
199
200impl<'borrow, const N: usize> Default for Cow<'borrow, N> {
201 fn default() -> Self {
202 Self::Borrowed("")
203 }
204}