1use std::{
2 borrow::Borrow,
3 fmt::{Debug, Display},
4 hash::Hash,
5 ops::Deref,
6 path::{Path, PathBuf},
7 sync::Arc,
8};
9
10pub enum CowArc<'a, T: ?Sized + 'static> {
20 Borrowed(&'a T),
22 Static(&'static T),
25 Owned(Arc<T>),
27}
28
29impl<'a, T: ?Sized> Deref for CowArc<'a, T> {
30 type Target = T;
31
32 #[inline]
33 fn deref(&self) -> &Self::Target {
34 match self {
35 CowArc::Borrowed(v) | CowArc::Static(v) => v,
36 CowArc::Owned(v) => v,
37 }
38 }
39}
40
41impl<'a, T: ?Sized> Borrow<T> for CowArc<'a, T> {
42 #[inline]
43 fn borrow(&self) -> &T {
44 self
45 }
46}
47
48impl<'a, T: ?Sized> AsRef<T> for CowArc<'a, T> {
49 #[inline]
50 fn as_ref(&self) -> &T {
51 self
52 }
53}
54
55impl<'a, T: ?Sized> CowArc<'a, T>
56where
57 &'a T: Into<Arc<T>>,
58{
59 #[inline]
62 pub fn into_owned(self) -> CowArc<'static, T> {
63 match self {
64 CowArc::Borrowed(value) => CowArc::Owned(value.into()),
65 CowArc::Static(value) => CowArc::Static(value),
66 CowArc::Owned(value) => CowArc::Owned(value),
67 }
68 }
69
70 #[inline]
74 pub fn clone_owned(&self) -> CowArc<'static, T> {
75 self.clone().into_owned()
76 }
77}
78
79impl<'a, T: ?Sized> Clone for CowArc<'a, T> {
80 #[inline]
81 fn clone(&self) -> Self {
82 match self {
83 Self::Borrowed(value) => Self::Borrowed(value),
84 Self::Static(value) => Self::Static(value),
85 Self::Owned(value) => Self::Owned(value.clone()),
86 }
87 }
88}
89
90impl<'a, T: PartialEq + ?Sized> PartialEq for CowArc<'a, T> {
91 #[inline]
92 fn eq(&self, other: &Self) -> bool {
93 self.deref().eq(other.deref())
94 }
95}
96
97impl<'a, T: PartialEq + ?Sized> Eq for CowArc<'a, T> {}
98
99impl<'a, T: Hash + ?Sized> Hash for CowArc<'a, T> {
100 #[inline]
101 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
102 self.deref().hash(state);
103 }
104}
105
106impl<'a, T: Debug + ?Sized> Debug for CowArc<'a, T> {
107 #[inline]
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109 Debug::fmt(self.deref(), f)
110 }
111}
112
113impl<'a, T: Display + ?Sized> Display for CowArc<'a, T> {
114 #[inline]
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 Display::fmt(self.deref(), f)
117 }
118}
119
120impl<'a, T: PartialOrd + ?Sized> PartialOrd for CowArc<'a, T> {
121 #[inline]
122 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
123 self.deref().partial_cmp(other.deref())
124 }
125}
126
127impl Default for CowArc<'static, str> {
128 fn default() -> Self {
129 CowArc::Static(Default::default())
130 }
131}
132
133impl Default for CowArc<'static, Path> {
134 fn default() -> Self {
135 CowArc::Static(Path::new(""))
136 }
137}
138
139impl<'a, T: Ord + ?Sized> Ord for CowArc<'a, T> {
140 #[inline]
141 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
142 self.deref().cmp(other.deref())
143 }
144}
145
146impl From<PathBuf> for CowArc<'static, Path> {
147 #[inline]
148 fn from(value: PathBuf) -> Self {
149 CowArc::Owned(value.into())
150 }
151}
152
153impl From<&'static str> for CowArc<'static, Path> {
154 #[inline]
155 fn from(value: &'static str) -> Self {
156 CowArc::Static(Path::new(value))
157 }
158}
159
160impl From<String> for CowArc<'static, str> {
161 #[inline]
162 fn from(value: String) -> Self {
163 CowArc::Owned(value.into())
164 }
165}
166
167impl<'a> From<&'a String> for CowArc<'a, str> {
168 #[inline]
169 fn from(value: &'a String) -> Self {
170 CowArc::Borrowed(value)
171 }
172}
173
174impl<T: ?Sized> From<&'static T> for CowArc<'static, T> {
175 #[inline]
176 fn from(value: &'static T) -> Self {
177 CowArc::Static(value)
178 }
179}