1#![doc = include_str!("../README.md")]
5
6use std::{
7 borrow::Borrow,
8 fmt::{Debug, Display},
9 hash::Hash,
10 ops::Deref,
11 path::{Path, PathBuf},
12 sync::Arc,
13};
14
15pub enum CowArc<'a, T: ?Sized + 'static> {
27 Borrowed(&'a T),
29 Static(&'static T),
35 Owned(Arc<T>),
37}
38
39impl<T: ?Sized + 'static> CowArc<'static, T> {
40 pub fn new_owned(value: T) -> Self
47 where
48 T: Sized,
49 {
50 CowArc::Owned(Arc::new(value))
51 }
52
53 pub fn new_owned_from_arc(value: impl Into<Arc<T>>) -> Self {
57 CowArc::Owned(value.into())
58 }
59}
60
61impl<T: ?Sized> CowArc<'static, T> {
62 #[inline]
68 pub fn as_static(self) -> Self {
69 match self {
70 Self::Borrowed(value) | Self::Static(value) => Self::Static(value),
71 Self::Owned(value) => Self::Owned(value),
72 }
73 }
74}
75
76impl<'a, T: ?Sized> Deref for CowArc<'a, T> {
77 type Target = T;
78
79 #[inline]
80 fn deref(&self) -> &Self::Target {
81 match self {
82 CowArc::Borrowed(v) | CowArc::Static(v) => v,
83 CowArc::Owned(v) => v,
84 }
85 }
86}
87
88impl<'a, T: ?Sized> Borrow<T> for CowArc<'a, T> {
89 #[inline]
90 fn borrow(&self) -> &T {
91 self
92 }
93}
94
95impl<'a, T: ?Sized> AsRef<T> for CowArc<'a, T> {
96 #[inline]
97 fn as_ref(&self) -> &T {
98 self
99 }
100}
101
102impl<'a, T: ?Sized> CowArc<'a, T>
103where
104 &'a T: Into<Arc<T>>,
105{
106 #[inline]
111 pub fn into_owned(self) -> CowArc<'static, T> {
112 match self {
113 CowArc::Borrowed(value) => CowArc::Owned(value.into()),
114 CowArc::Static(value) => CowArc::Static(value),
115 CowArc::Owned(value) => CowArc::Owned(value),
116 }
117 }
118
119 #[inline]
125 pub fn clone_owned(&self) -> CowArc<'static, T> {
126 self.clone().into_owned()
127 }
128}
129
130impl<'a, T: ?Sized> Clone for CowArc<'a, T> {
131 #[inline]
132 fn clone(&self) -> Self {
133 match self {
134 Self::Borrowed(value) => Self::Borrowed(value),
135 Self::Static(value) => Self::Static(value),
136 Self::Owned(value) => Self::Owned(value.clone()),
137 }
138 }
139}
140
141impl<'a, T: PartialEq + ?Sized> PartialEq for CowArc<'a, T> {
142 #[inline]
143 fn eq(&self, other: &Self) -> bool {
144 self.deref().eq(other.deref())
145 }
146}
147
148impl<'a, T: PartialEq + ?Sized> Eq for CowArc<'a, T> {}
149
150impl<'a, T: Hash + ?Sized> Hash for CowArc<'a, T> {
151 #[inline]
152 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
153 self.deref().hash(state);
154 }
155}
156
157impl<'a, T: Debug + ?Sized> Debug for CowArc<'a, T> {
158 #[inline]
159 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
160 Debug::fmt(self.deref(), f)
161 }
162}
163
164impl<'a, T: Display + ?Sized> Display for CowArc<'a, T> {
165 #[inline]
166 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
167 Display::fmt(self.deref(), f)
168 }
169}
170
171impl<'a, T: PartialOrd + ?Sized> PartialOrd for CowArc<'a, T> {
172 #[inline]
173 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
174 self.deref().partial_cmp(other.deref())
175 }
176}
177
178impl Default for CowArc<'static, str> {
179 fn default() -> Self {
180 CowArc::Static(Default::default())
181 }
182}
183
184impl Default for CowArc<'static, Path> {
186 fn default() -> Self {
190 CowArc::Static(Path::new(""))
191 }
192}
193
194impl<'a, T: Ord + ?Sized> Ord for CowArc<'a, T> {
195 #[inline]
196 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
197 self.deref().cmp(other.deref())
198 }
199}
200
201impl From<PathBuf> for CowArc<'static, Path> {
202 #[inline]
203 fn from(value: PathBuf) -> Self {
204 CowArc::Owned(value.into())
205 }
206}
207
208impl From<&'static str> for CowArc<'static, Path> {
209 #[inline]
210 fn from(value: &'static str) -> Self {
211 CowArc::Static(Path::new(value))
212 }
213}
214
215impl From<String> for CowArc<'static, str> {
216 #[inline]
217 fn from(value: String) -> Self {
218 CowArc::Owned(value.into())
219 }
220}
221
222impl<'a> From<&'a String> for CowArc<'a, str> {
223 #[inline]
224 fn from(value: &'a String) -> Self {
225 CowArc::Borrowed(value)
226 }
227}
228
229impl<T: ?Sized> From<&'static T> for CowArc<'static, T> {
230 #[inline]
231 fn from(value: &'static T) -> Self {
232 CowArc::Static(value)
233 }
234}
235
236impl<T> From<Arc<T>> for CowArc<'static, T> {
237 #[inline]
238 fn from(value: Arc<T>) -> Self {
239 CowArc::Owned(value)
240 }
241}