1use std::borrow::Borrow;
2use std::fmt::Formatter;
3use std::ops::Deref;
4use std::path;
5
6use camino::{Utf8Components, Utf8Path, Utf8PathBuf};
7
8#[repr(transparent)]
9#[derive(Debug, Eq, PartialEq, Hash)]
10pub struct VendoredPath(Utf8Path);
11
12impl VendoredPath {
13 pub fn new(path: &(impl AsRef<Utf8Path> + ?Sized)) -> &Self {
14 let path = path.as_ref();
15 unsafe { &*(path as *const Utf8Path as *const VendoredPath) }
18 }
19
20 pub fn file_name(&self) -> Option<&str> {
21 self.0.file_name()
22 }
23
24 pub fn to_path_buf(&self) -> VendoredPathBuf {
25 VendoredPathBuf(self.0.to_path_buf())
26 }
27
28 pub fn as_str(&self) -> &str {
29 self.0.as_str()
30 }
31
32 pub fn as_utf8_path(&self) -> &camino::Utf8Path {
33 &self.0
34 }
35
36 pub fn as_std_path(&self) -> &path::Path {
37 self.0.as_std_path()
38 }
39
40 pub fn components(&self) -> Utf8Components<'_> {
41 self.0.components()
42 }
43
44 #[must_use]
45 pub fn extension(&self) -> Option<&str> {
46 self.0.extension()
47 }
48
49 #[must_use]
50 pub fn with_pyi_extension(&self) -> VendoredPathBuf {
51 VendoredPathBuf(self.0.with_extension("pyi"))
52 }
53
54 #[must_use]
55 pub fn join(&self, other: impl AsRef<VendoredPath>) -> VendoredPathBuf {
56 VendoredPathBuf(self.0.join(other.as_ref()))
57 }
58
59 #[must_use]
60 pub fn ends_with(&self, suffix: impl AsRef<VendoredPath>) -> bool {
61 self.0.ends_with(suffix.as_ref())
62 }
63
64 #[must_use]
65 pub fn parent(&self) -> Option<&Self> {
66 self.0.parent().map(Self::new)
67 }
68
69 #[must_use]
70 pub fn file_stem(&self) -> Option<&str> {
71 self.0.file_stem()
72 }
73
74 pub fn strip_prefix(
75 &self,
76 prefix: impl AsRef<VendoredPath>,
77 ) -> Result<&Self, path::StripPrefixError> {
78 self.0.strip_prefix(prefix.as_ref()).map(Self::new)
79 }
80}
81
82impl ToOwned for VendoredPath {
83 type Owned = VendoredPathBuf;
84
85 fn to_owned(&self) -> VendoredPathBuf {
86 self.to_path_buf()
87 }
88}
89
90#[repr(transparent)]
91#[derive(Debug, Eq, PartialEq, Clone, Hash)]
92pub struct VendoredPathBuf(Utf8PathBuf);
93
94impl get_size2::GetSize for VendoredPathBuf {
95 fn get_heap_size_with_tracker<T: get_size2::GetSizeTracker>(&self, tracker: T) -> (usize, T) {
96 (self.0.capacity(), tracker)
97 }
98}
99
100impl Default for VendoredPathBuf {
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106impl VendoredPathBuf {
107 pub fn new() -> Self {
108 Self(Utf8PathBuf::new())
109 }
110
111 #[inline]
112 pub fn as_path(&self) -> &VendoredPath {
113 VendoredPath::new(&self.0)
114 }
115
116 pub fn push(&mut self, component: impl AsRef<VendoredPath>) {
117 self.0.push(component.as_ref())
118 }
119}
120
121impl From<&VendoredPath> for Box<VendoredPath> {
122 fn from(path: &VendoredPath) -> Self {
123 Box::from(path.to_path_buf())
124 }
125}
126
127impl From<VendoredPathBuf> for Box<VendoredPath> {
128 fn from(path: VendoredPathBuf) -> Self {
129 let path = Box::into_raw(path.0.into_boxed_path()) as *mut VendoredPath;
130 unsafe { Box::from_raw(path) }
133 }
134}
135
136impl Clone for Box<VendoredPath> {
137 fn clone(&self) -> Self {
138 Box::from(&**self)
139 }
140}
141
142impl get_size2::GetSize for Box<VendoredPath> {
143 fn get_heap_size_with_tracker<T: get_size2::GetSizeTracker>(&self, tracker: T) -> (usize, T) {
144 (std::mem::size_of_val(&**self), tracker)
145 }
146}
147
148impl Borrow<VendoredPath> for VendoredPathBuf {
149 fn borrow(&self) -> &VendoredPath {
150 self.as_path()
151 }
152}
153
154impl AsRef<VendoredPath> for VendoredPathBuf {
155 fn as_ref(&self) -> &VendoredPath {
156 self.as_path()
157 }
158}
159
160impl AsRef<VendoredPath> for VendoredPath {
161 #[inline]
162 fn as_ref(&self) -> &VendoredPath {
163 self
164 }
165}
166
167impl AsRef<VendoredPath> for Utf8Path {
168 #[inline]
169 fn as_ref(&self) -> &VendoredPath {
170 VendoredPath::new(self)
171 }
172}
173
174impl AsRef<VendoredPath> for Utf8PathBuf {
175 #[inline]
176 fn as_ref(&self) -> &VendoredPath {
177 VendoredPath::new(self.as_path())
178 }
179}
180
181impl AsRef<VendoredPath> for str {
182 #[inline]
183 fn as_ref(&self) -> &VendoredPath {
184 VendoredPath::new(self)
185 }
186}
187
188impl AsRef<VendoredPath> for String {
189 #[inline]
190 fn as_ref(&self) -> &VendoredPath {
191 VendoredPath::new(self)
192 }
193}
194
195impl AsRef<path::Path> for VendoredPath {
196 #[inline]
197 fn as_ref(&self) -> &path::Path {
198 self.0.as_std_path()
199 }
200}
201
202impl AsRef<Utf8Path> for VendoredPath {
203 #[inline]
204 fn as_ref(&self) -> &Utf8Path {
205 &self.0
206 }
207}
208
209impl Deref for VendoredPathBuf {
210 type Target = VendoredPath;
211
212 fn deref(&self) -> &Self::Target {
213 self.as_path()
214 }
215}
216
217impl From<&str> for VendoredPathBuf {
218 fn from(value: &str) -> Self {
219 Self(Utf8PathBuf::from(value))
220 }
221}
222
223impl<'a> TryFrom<&'a path::Path> for &'a VendoredPath {
224 type Error = camino::FromPathError;
225
226 fn try_from(value: &'a path::Path) -> Result<Self, Self::Error> {
227 Ok(VendoredPath::new(<&camino::Utf8Path>::try_from(value)?))
228 }
229}
230
231impl TryFrom<path::PathBuf> for VendoredPathBuf {
232 type Error = camino::FromPathBufError;
233
234 fn try_from(value: path::PathBuf) -> Result<Self, Self::Error> {
235 Ok(VendoredPathBuf(camino::Utf8PathBuf::try_from(value)?))
236 }
237}
238
239impl std::fmt::Display for VendoredPath {
240 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
241 write!(f, "vendored://{}", &self.0)
242 }
243}
244
245impl std::fmt::Display for VendoredPathBuf {
246 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
247 std::fmt::Display::fmt(self.as_path(), f)
248 }
249}