1#![doc = include_str!("../README.md")]
2
3pub trait MaybeOwned {
5 type Owned;
7 type Borrowed<'a>
9 where
10 Self: 'a;
11 fn to_owned(self) -> Self::Owned;
13 fn borrow(&self) -> Self::Borrowed<'_>;
15}
16
17impl<'s> MaybeOwned for &'s str {
18 type Owned = String;
19 type Borrowed<'a> = &'a str
20 where
21 's: 'a;
22 fn to_owned(self) -> Self::Owned {
23 self.to_string()
24 }
25 fn borrow(&self) -> Self::Borrowed<'_> {
26 self
27 }
28}
29
30impl MaybeOwned for String {
31 type Owned = String;
32 type Borrowed<'a> = &'a str;
33 fn to_owned(self) -> Self::Owned {
34 self
35 }
36 fn borrow(&self) -> Self::Borrowed<'_> {
37 self.as_str()
38 }
39}
40
41impl<'s> MaybeOwned for std::borrow::Cow<'s, str> {
42 type Owned = String;
43 type Borrowed<'a> = &'a str
44 where
45 's: 'a;
46 fn to_owned(self) -> <Self as MaybeOwned>::Owned {
47 self.into_owned()
48 }
49 fn borrow(&self) -> <Self as MaybeOwned>::Borrowed<'_> {
50 self.as_ref()
51 }
52}
53
54#[cfg(feature = "beef")]
55impl<'s> MaybeOwned for beef::Cow<'s, str> {
56 type Owned = String;
57 type Borrowed<'a> = &'a str
58 where
59 's: 'a;
60 fn to_owned(self) -> <Self as MaybeOwned>::Owned {
61 self.into_owned()
62 }
63 fn borrow(&self) -> <Self as MaybeOwned>::Borrowed<'_> {
64 self.as_ref()
65 }
66}
67
68#[cfg(all(feature = "beef", target_pointer_width = "64"))]
69impl<'s> MaybeOwned for beef::lean::Cow<'s, str> {
70 type Owned = String;
71 type Borrowed<'a> = &'a str
72 where
73 's: 'a;
74 fn to_owned(self) -> <Self as MaybeOwned>::Owned {
75 self.into_owned()
76 }
77 fn borrow(&self) -> <Self as MaybeOwned>::Borrowed<'_> {
78 self.as_ref()
79 }
80}
81
82impl<'a, T: Clone> MaybeOwned for &'a [T] {
83 type Owned = Vec<T>;
84 type Borrowed<'b> = &'b [T]
85 where
86 T: 'b,
87 Self: 'b;
88
89 fn to_owned(self) -> Self::Owned {
90 self.to_vec()
91 }
92
93 fn borrow(&self) -> Self::Borrowed<'_> {
94 self
95 }
96}
97
98impl<T> MaybeOwned for Vec<T> {
99 type Owned = Vec<T>;
100 type Borrowed<'a> = &'a [T]
101 where T: 'a;
102
103 fn to_owned(self) -> Self::Owned {
104 self
105 }
106
107 fn borrow(&self) -> Self::Borrowed<'_> {
108 self.as_slice()
109 }
110}
111
112impl<'s> MaybeOwned for &'s std::path::Path {
113 type Owned = std::path::PathBuf;
114 type Borrowed<'a> = &'a std::path::Path
115 where
116 's: 'a;
117
118 fn to_owned(self) -> Self::Owned {
119 self.to_path_buf()
120 }
121
122 fn borrow(&self) -> Self::Borrowed<'_> {
123 self
124 }
125}
126
127impl MaybeOwned for std::path::PathBuf {
128 type Owned = std::path::PathBuf;
129 type Borrowed<'a> = &'a std::path::Path;
130
131 fn to_owned(self) -> Self::Owned {
132 self
133 }
134
135 fn borrow(&self) -> Self::Borrowed<'_> {
136 self.as_path()
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use rand::Rng;
143 use std::path::{Path, PathBuf};
144
145 use super::MaybeOwned;
146
147 #[test]
148 #[ignore = "This test exists to ensure that the code compiles"]
149 fn simple_test() {
150 fn my_fn(path: impl MaybeOwned<Owned = PathBuf>) {
151 let path = path.to_owned();
152 println!("{:?}", path);
153 }
154
155 my_fn(PathBuf::from("hello"));
156 }
157
158 #[test]
159 #[ignore = "This test exists to ensure that the code compiles"]
160 fn complicated_test() {
161 fn my_fn(path: impl for<'a> MaybeOwned<Owned = PathBuf, Borrowed<'a> = &'a Path>) {
162 if rand::thread_rng().gen::<bool>() {
163 let path_buf: PathBuf = path.to_owned();
164 println!("Owned buf: {:?}", path_buf);
165 } else {
166 let path: &Path = path.borrow();
167 println!("Borrowed path: {:?}", path);
168 };
169 }
170
171 my_fn(PathBuf::from("hello"));
172 my_fn(Path::new("hello"));
173 }
174}