nu_path/
path.rs

1use crate::form::{
2    Absolute, Any, Canonical, IsAbsolute, MaybeRelative, PathCast, PathForm, PathJoin, PathPush,
3    PathSet, Relative,
4};
5use ref_cast::{RefCastCustom, ref_cast_custom};
6use std::{
7    borrow::{Borrow, Cow},
8    cmp::Ordering,
9    collections::TryReserveError,
10    convert::Infallible,
11    ffi::{OsStr, OsString},
12    fmt, fs,
13    hash::{Hash, Hasher},
14    io,
15    iter::FusedIterator,
16    marker::PhantomData,
17    ops::{Deref, DerefMut},
18    path::StripPrefixError,
19    rc::Rc,
20    str::FromStr,
21    sync::Arc,
22};
23
24/// A wrapper around [`std::path::Path`] with extra invariants determined by its `Form`.
25///
26/// The possible path forms are [`Any`], [`Relative`], [`Absolute`], or [`Canonical`].
27/// To learn more, view the documentation on [`PathForm`] or any of the individual forms.
28///
29/// There are also several type aliases available, corresponding to each [`PathForm`]:
30/// - [`RelativePath`] (same as [`Path<Relative>`])
31/// - [`AbsolutePath`] (same as [`Path<Absolute>`])
32/// - [`CanonicalPath`] (same as [`Path<Canonical>`])
33///
34/// If the `Form` is not specified, then it defaults to [`Any`], so [`Path`] and [`Path<Any>`]
35/// are one in the same.
36///
37/// # Converting to [`std::path`] types
38///
39/// [`Path`]s with form [`Any`] cannot be easily referenced as a [`std::path::Path`] by design.
40/// Other Nushell crates need to account for the emulated current working directory
41/// before passing a path to functions in [`std`] or other third party crates.
42/// You can [`join`](Path::join) a [`Path`] onto an [`AbsolutePath`] or a [`CanonicalPath`].
43/// This will return an [`AbsolutePathBuf`] which can be easily referenced as a [`std::path::Path`].
44/// If you really mean it, you can instead use [`as_relative_std_path`](Path::as_relative_std_path)
45/// to get the underlying [`std::path::Path`] from a [`Path`].
46/// But this may cause third-party code to use [`std::env::current_dir`] to resolve
47/// the path which is almost always incorrect behavior. Extra care is needed to ensure that this
48/// is not the case after using [`as_relative_std_path`](Path::as_relative_std_path).
49#[derive(RefCastCustom)]
50#[repr(transparent)]
51pub struct Path<Form = Any> {
52    _form: PhantomData<Form>,
53    inner: std::path::Path,
54}
55
56/// A path that is strictly relative.
57///
58/// I.e., this path is guaranteed to never be absolute.
59///
60/// [`RelativePath`]s cannot be easily converted into a [`std::path::Path`] by design.
61/// Other Nushell crates need to account for the emulated current working directory
62/// before passing a path to functions in [`std`] or other third party crates.
63/// You can [`join`](Path::join) a [`RelativePath`] onto an [`AbsolutePath`] or a [`CanonicalPath`].
64/// This will return an [`AbsolutePathBuf`] which can be referenced as a [`std::path::Path`].
65/// If you really mean it, you can use [`as_relative_std_path`](RelativePath::as_relative_std_path)
66/// to get the underlying [`std::path::Path`] from a [`RelativePath`].
67/// But this may cause third-party code to use [`std::env::current_dir`] to resolve
68/// the path which is almost always incorrect behavior. Extra care is needed to ensure that this
69/// is not the case after using [`as_relative_std_path`](RelativePath::as_relative_std_path).
70///
71/// # Examples
72///
73/// [`RelativePath`]s can be created by using [`try_relative`](Path::try_relative)
74/// on a [`Path`], by using [`try_new`](Path::try_new), or by using
75/// [`strip_prefix`](Path::strip_prefix) on a [`Path`] of any form.
76///
77/// ```
78/// use nu_path::{Path, RelativePath};
79///
80/// let path1 = Path::new("foo.txt");
81/// let path1 = path1.try_relative().unwrap();
82///
83/// let path2 = RelativePath::try_new("foo.txt").unwrap();
84///
85/// let path3 = Path::new("/prefix/foo.txt").strip_prefix("/prefix").unwrap();
86///
87/// assert_eq!(path1, path2);
88/// assert_eq!(path2, path3);
89/// ```
90///
91/// You can also use `RelativePath::try_from` or `try_into`.
92/// This supports attempted conversions from [`Path`] as well as types in [`std::path`].
93///
94/// ```
95/// use nu_path::{Path, RelativePath};
96///
97/// let path1 = Path::new("foo.txt");
98/// let path1: &RelativePath = path1.try_into().unwrap();
99///
100/// let path2 = std::path::Path::new("foo.txt");
101/// let path2: &RelativePath = path2.try_into().unwrap();
102///
103/// assert_eq!(path1, path2)
104/// ```
105pub type RelativePath = Path<Relative>;
106
107/// A path that is strictly absolute.
108///
109/// I.e., this path is guaranteed to never be relative.
110///
111/// # Examples
112///
113/// [`AbsolutePath`]s can be created by using [`try_absolute`](Path::try_absolute) on a [`Path`]
114/// or by using [`try_new`](AbsolutePath::try_new).
115///
116#[cfg_attr(not(windows), doc = "```")]
117#[cfg_attr(windows, doc = "```no_run")]
118/// use nu_path::{AbsolutePath, Path};
119///
120/// let path1 = Path::new("/foo").try_absolute().unwrap();
121/// let path2 = AbsolutePath::try_new("/foo").unwrap();
122///
123/// assert_eq!(path1, path2);
124/// ```
125///
126/// You can also use `AbsolutePath::try_from` or `try_into`.
127/// This supports attempted conversions from [`Path`] as well as types in [`std::path`].
128///
129#[cfg_attr(not(windows), doc = "```")]
130#[cfg_attr(windows, doc = "```no_run")]
131/// use nu_path::{AbsolutePath, Path};
132///
133/// let path1 = Path::new("/foo");
134/// let path1: &AbsolutePath = path1.try_into().unwrap();
135///
136/// let path2 = std::path::Path::new("/foo");
137/// let path2: &AbsolutePath = path2.try_into().unwrap();
138///
139/// assert_eq!(path1, path2)
140/// ```
141pub type AbsolutePath = Path<Absolute>;
142
143/// An absolute, canonical path.
144///
145/// # Examples
146///
147/// [`CanonicalPath`]s can only be created by using [`canonicalize`](Path::canonicalize) on
148/// an [`AbsolutePath`]. References to [`CanonicalPath`]s can be converted to
149/// [`AbsolutePath`] references using `as_ref`, [`cast`](Path::cast),
150/// or [`as_absolute`](CanonicalPath::as_absolute).
151///
152/// ```no_run
153/// use nu_path::AbsolutePath;
154///
155/// let path = AbsolutePath::try_new("/foo").unwrap();
156///
157/// let canonical = path.canonicalize().expect("canonicalization failed");
158///
159/// assert_eq!(path, canonical.as_absolute());
160/// ```
161pub type CanonicalPath = Path<Canonical>;
162
163impl<Form: PathForm> Path<Form> {
164    /// Create a new path of any form without validating invariants.
165    #[inline]
166    fn new_unchecked<P: AsRef<OsStr> + ?Sized>(path: &P) -> &Self {
167        #[ref_cast_custom]
168        fn ref_cast<Form: PathForm>(path: &std::path::Path) -> &Path<Form>;
169
170        debug_assert!(Form::invariants_satisfied(path));
171        ref_cast(std::path::Path::new(path))
172    }
173
174    /// Attempt to create a new [`Path`] from a reference of another type.
175    ///
176    /// This is a convenience method instead of having to use `try_into` with a type annotation.
177    ///
178    /// # Examples
179    ///
180    /// ```
181    /// use nu_path::{AbsolutePath, RelativePath};
182    ///
183    /// assert!(AbsolutePath::try_new("foo.txt").is_err());
184    /// assert!(RelativePath::try_new("foo.txt").is_ok());
185    /// ```
186    #[inline]
187    pub fn try_new<'a, T>(path: &'a T) -> Result<&'a Self, <&'a T as TryInto<&'a Self>>::Error>
188    where
189        T: ?Sized,
190        &'a T: TryInto<&'a Self>,
191    {
192        path.try_into()
193    }
194
195    /// Returns the underlying [`OsStr`] slice.
196    ///
197    /// # Examples
198    ///
199    /// ```
200    /// use nu_path::Path;
201    ///
202    /// let os_str = Path::new("foo.txt").as_os_str();
203    /// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt"));
204    /// ```
205    #[must_use]
206    #[inline]
207    pub fn as_os_str(&self) -> &OsStr {
208        self.inner.as_os_str()
209    }
210
211    /// Returns a [`str`] slice if the [`Path`] is valid unicode.
212    ///
213    /// # Examples
214    ///
215    /// ```
216    /// use nu_path::Path;
217    ///
218    /// let path = Path::new("foo.txt");
219    /// assert_eq!(path.to_str(), Some("foo.txt"));
220    /// ```
221    #[inline]
222    pub fn to_str(&self) -> Option<&str> {
223        self.inner.to_str()
224    }
225
226    /// Converts a [`Path`] to a `Cow<str>`.
227    ///
228    /// Any non-Unicode sequences are replaced with `U+FFFD REPLACEMENT CHARACTER`.
229    ///
230    /// # Examples
231    ///
232    /// Calling `to_string_lossy` on a [`Path`] with valid unicode:
233    ///
234    /// ```
235    /// use nu_path::Path;
236    ///
237    /// let path = Path::new("foo.txt");
238    /// assert_eq!(path.to_string_lossy(), "foo.txt");
239    /// ```
240    ///
241    /// Had `path` contained invalid unicode, the `to_string_lossy` call might have returned
242    /// `"fo�.txt"`.
243    #[inline]
244    pub fn to_string_lossy(&self) -> Cow<'_, str> {
245        self.inner.to_string_lossy()
246    }
247
248    /// Converts a [`Path`] to an owned [`PathBuf`].
249    ///
250    /// # Examples
251    ///
252    /// ```
253    /// use nu_path::{Path, PathBuf};
254    ///
255    /// let path_buf = Path::new("foo.txt").to_path_buf();
256    /// assert_eq!(path_buf, PathBuf::from("foo.txt"));
257    /// ```
258    #[inline]
259    pub fn to_path_buf(&self) -> PathBuf<Form> {
260        PathBuf::new_unchecked(self.inner.to_path_buf())
261    }
262
263    /// Returns the [`Path`] without its final component, if there is one.
264    ///
265    /// This means it returns `Some("")` for relative paths with one component.
266    ///
267    /// Returns [`None`] if the path terminates in a root or prefix, or if it's
268    /// the empty string.
269    ///
270    /// # Examples
271    ///
272    /// ```
273    /// use nu_path::Path;
274    ///
275    /// let path = Path::new("/foo/bar");
276    /// let parent = path.parent().unwrap();
277    /// assert_eq!(parent, Path::new("/foo"));
278    ///
279    /// let grand_parent = parent.parent().unwrap();
280    /// assert_eq!(grand_parent, Path::new("/"));
281    /// assert_eq!(grand_parent.parent(), None);
282    ///
283    /// let relative_path = Path::new("foo/bar");
284    /// let parent = relative_path.parent();
285    /// assert_eq!(parent, Some(Path::new("foo")));
286    /// let grand_parent = parent.and_then(Path::parent);
287    /// assert_eq!(grand_parent, Some(Path::new("")));
288    /// let great_grand_parent = grand_parent.and_then(Path::parent);
289    /// assert_eq!(great_grand_parent, None);
290    /// ```
291    #[must_use]
292    #[inline]
293    pub fn parent(&self) -> Option<&Self> {
294        self.inner.parent().map(Self::new_unchecked)
295    }
296
297    /// Produces an iterator over a [`Path`] and its ancestors.
298    ///
299    /// The iterator will yield the [`Path`] that is returned if the [`parent`](Path::parent) method
300    /// is used zero or more times. That means, the iterator will yield `&self`,
301    /// `&self.parent().unwrap()`, `&self.parent().unwrap().parent().unwrap()` and so on.
302    /// If the [`parent`](Path::parent) method returns [`None`], the iterator will do likewise.
303    /// The iterator will always yield at least one value, namely `&self`.
304    ///
305    /// # Examples
306    ///
307    /// ```
308    /// use nu_path::Path;
309    ///
310    /// let mut ancestors = Path::new("/foo/bar").ancestors();
311    /// assert_eq!(ancestors.next(), Some(Path::new("/foo/bar")));
312    /// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
313    /// assert_eq!(ancestors.next(), Some(Path::new("/")));
314    /// assert_eq!(ancestors.next(), None);
315    ///
316    /// let mut ancestors = Path::new("../foo/bar").ancestors();
317    /// assert_eq!(ancestors.next(), Some(Path::new("../foo/bar")));
318    /// assert_eq!(ancestors.next(), Some(Path::new("../foo")));
319    /// assert_eq!(ancestors.next(), Some(Path::new("..")));
320    /// assert_eq!(ancestors.next(), Some(Path::new("")));
321    /// assert_eq!(ancestors.next(), None);
322    /// ```
323    #[inline]
324    pub fn ancestors(&self) -> Ancestors<'_, Form> {
325        Ancestors {
326            _form: PhantomData,
327            inner: self.inner.ancestors(),
328        }
329    }
330
331    /// Returns the final component of a [`Path`], if there is one.
332    ///
333    /// If the path is a normal file, this is the file name. If it's the path of a directory, this
334    /// is the directory name.
335    ///
336    /// Returns [`None`] if the path terminates in `..`.
337    ///
338    /// # Examples
339    ///
340    /// ```
341    /// use nu_path::Path;
342    /// use std::ffi::OsStr;
343    ///
344    /// assert_eq!(Some(OsStr::new("bin")), Path::new("/usr/bin/").file_name());
345    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("tmp/foo.txt").file_name());
346    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.").file_name());
347    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.//").file_name());
348    /// assert_eq!(None, Path::new("foo.txt/..").file_name());
349    /// assert_eq!(None, Path::new("/").file_name());
350    /// ```
351    #[must_use]
352    #[inline]
353    pub fn file_name(&self) -> Option<&OsStr> {
354        self.inner.file_name()
355    }
356
357    /// Returns a relative path that, when joined onto `base`, yields `self`.
358    ///
359    /// # Examples
360    ///
361    /// ```
362    /// use nu_path::{Path, PathBuf};
363    ///
364    /// let path = Path::new("/test/haha/foo.txt");
365    ///
366    /// assert_eq!(path.strip_prefix("/").unwrap(), Path::new("test/haha/foo.txt"));
367    /// assert_eq!(path.strip_prefix("/test").unwrap(), Path::new("haha/foo.txt"));
368    /// assert_eq!(path.strip_prefix("/test/").unwrap(), Path::new("haha/foo.txt"));
369    /// assert_eq!(path.strip_prefix("/test/haha/foo.txt").unwrap(), Path::new(""));
370    /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/").unwrap(), Path::new(""));
371    ///
372    /// assert!(path.strip_prefix("test").is_err());
373    /// assert!(path.strip_prefix("/haha").is_err());
374    ///
375    /// let prefix = PathBuf::from("/test/");
376    /// assert_eq!(path.strip_prefix(prefix).unwrap(), Path::new("haha/foo.txt"));
377    /// ```
378    #[inline]
379    pub fn strip_prefix(&self, base: impl AsRef<Path>) -> Result<&RelativePath, StripPrefixError> {
380        self.inner
381            .strip_prefix(&base.as_ref().inner)
382            .map(RelativePath::new_unchecked)
383    }
384
385    /// Determines whether `base` is a prefix of `self`.
386    ///
387    /// Only considers whole path components to match.
388    ///
389    /// # Examples
390    ///
391    /// ```
392    /// use nu_path::Path;
393    ///
394    /// let path = Path::new("/etc/passwd");
395    ///
396    /// assert!(path.starts_with("/etc"));
397    /// assert!(path.starts_with("/etc/"));
398    /// assert!(path.starts_with("/etc/passwd"));
399    /// assert!(path.starts_with("/etc/passwd/")); // extra slash is okay
400    /// assert!(path.starts_with("/etc/passwd///")); // multiple extra slashes are okay
401    ///
402    /// assert!(!path.starts_with("/e"));
403    /// assert!(!path.starts_with("/etc/passwd.txt"));
404    ///
405    /// assert!(!Path::new("/etc/foo.rs").starts_with("/etc/foo"));
406    /// ```
407    #[must_use]
408    #[inline]
409    pub fn starts_with(&self, base: impl AsRef<Path>) -> bool {
410        self.inner.starts_with(&base.as_ref().inner)
411    }
412
413    /// Determines whether `child` is a suffix of `self`.
414    ///
415    /// Only considers whole path components to match.
416    ///
417    /// # Examples
418    ///
419    /// ```
420    /// use nu_path::Path;
421    ///
422    /// let path = Path::new("/etc/resolv.conf");
423    ///
424    /// assert!(path.ends_with("resolv.conf"));
425    /// assert!(path.ends_with("etc/resolv.conf"));
426    /// assert!(path.ends_with("/etc/resolv.conf"));
427    ///
428    /// assert!(!path.ends_with("/resolv.conf"));
429    /// assert!(!path.ends_with("conf")); // use .extension() instead
430    /// ```
431    #[must_use]
432    #[inline]
433    pub fn ends_with(&self, child: impl AsRef<Path>) -> bool {
434        self.inner.ends_with(&child.as_ref().inner)
435    }
436
437    /// Extracts the stem (non-extension) portion of [`self.file_name`](Path::file_name).
438    ///
439    /// The stem is:
440    ///
441    /// * [`None`], if there is no file name;
442    /// * The entire file name if there is no embedded `.`;
443    /// * The entire file name if the file name begins with `.` and has no other `.`s within;
444    /// * Otherwise, the portion of the file name before the final `.`
445    ///
446    /// # Examples
447    ///
448    /// ```
449    /// use nu_path::Path;
450    ///
451    /// assert_eq!("foo", Path::new("foo.rs").file_stem().unwrap());
452    /// assert_eq!("foo.tar", Path::new("foo.tar.gz").file_stem().unwrap());
453    /// ```
454    #[must_use]
455    #[inline]
456    pub fn file_stem(&self) -> Option<&OsStr> {
457        self.inner.file_stem()
458    }
459
460    /// Extracts the extension (without the leading dot) of [`self.file_name`](Path::file_name),
461    /// if possible.
462    ///
463    /// The extension is:
464    ///
465    /// * [`None`], if there is no file name;
466    /// * [`None`], if there is no embedded `.`;
467    /// * [`None`], if the file name begins with `.` and has no other `.`s within;
468    /// * Otherwise, the portion of the file name after the final `.`
469    ///
470    /// # Examples
471    ///
472    /// ```
473    /// use nu_path::Path;
474    ///
475    /// assert_eq!("rs", Path::new("foo.rs").extension().unwrap());
476    /// assert_eq!("gz", Path::new("foo.tar.gz").extension().unwrap());
477    /// ```
478    #[must_use]
479    #[inline]
480    pub fn extension(&self) -> Option<&OsStr> {
481        self.inner.extension()
482    }
483
484    /// Produces an iterator over the [`Component`](std::path::Component)s of the path.
485    ///
486    /// When parsing the path, there is a small amount of normalization:
487    ///
488    /// * Repeated separators are ignored, so `a/b` and `a//b` both have
489    ///   `a` and `b` as components.
490    ///
491    /// * Occurrences of `.` are normalized away, except if they are at the
492    ///   beginning of the path. For example, `a/./b`, `a/b/`, `a/b/.` and
493    ///   `a/b` all have `a` and `b` as components, but `./a/b` starts with
494    ///   an additional [`CurDir`](std::path::Component) component.
495    ///
496    /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
497    ///
498    /// Note that no other normalization takes place; in particular, `a/c`
499    /// and `a/b/../c` are distinct, to account for the possibility that `b`
500    /// is a symbolic link (so its parent isn't `a`).
501    ///
502    /// # Examples
503    ///
504    /// ```
505    /// use nu_path::Path;
506    /// use std::path::Component;
507    /// use std::ffi::OsStr;
508    ///
509    /// let mut components = Path::new("/tmp/foo.txt").components();
510    ///
511    /// assert_eq!(components.next(), Some(Component::RootDir));
512    /// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("tmp"))));
513    /// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("foo.txt"))));
514    /// assert_eq!(components.next(), None)
515    /// ```
516    #[inline]
517    pub fn components(&self) -> std::path::Components<'_> {
518        self.inner.components()
519    }
520
521    /// Produces an iterator over the path's components viewed as [`OsStr`] slices.
522    ///
523    /// For more information about the particulars of how the path is separated into components,
524    /// see [`components`](Path::components).
525    ///
526    /// # Examples
527    ///
528    /// ```
529    /// use nu_path::Path;
530    /// use std::ffi::OsStr;
531    ///
532    /// let mut it = Path::new("/tmp/foo.txt").iter();
533    /// assert_eq!(it.next(), Some(OsStr::new(&std::path::MAIN_SEPARATOR.to_string())));
534    /// assert_eq!(it.next(), Some(OsStr::new("tmp")));
535    /// assert_eq!(it.next(), Some(OsStr::new("foo.txt")));
536    /// assert_eq!(it.next(), None)
537    /// ```
538    #[inline]
539    pub fn iter(&self) -> std::path::Iter<'_> {
540        self.inner.iter()
541    }
542
543    /// Returns an object that implements [`Display`](fmt::Display) for safely printing paths
544    /// that may contain non-Unicode data. This may perform lossy conversion,
545    /// depending on the platform. If you would like an implementation which escapes the path
546    /// please use [`Debug`](fmt::Debug) instead.
547    ///
548    /// # Examples
549    ///
550    /// ```
551    /// use nu_path::Path;
552    ///
553    /// let path = Path::new("/tmp/foo.rs");
554    ///
555    /// println!("{}", path.display());
556    /// ```
557    #[inline]
558    pub fn display(&self) -> std::path::Display<'_> {
559        self.inner.display()
560    }
561
562    /// Converts a [`Box<Path>`](Box) into a [`PathBuf`] without copying or allocating.
563    #[inline]
564    pub fn into_path_buf(self: Box<Self>) -> PathBuf<Form> {
565        // Safety: `Path<Form>` is a repr(transparent) wrapper around `std::path::Path`.
566        let ptr = Box::into_raw(self) as *mut std::path::Path;
567        let boxed = unsafe { Box::from_raw(ptr) };
568        PathBuf::new_unchecked(boxed.into_path_buf())
569    }
570
571    /// Returns a reference to the same [`Path`] in a different form.
572    ///
573    /// [`PathForm`]s can be converted to one another based on [`PathCast`] implementations.
574    /// Namely, the following form conversions are possible:
575    /// - [`Relative`], [`Absolute`], or [`Canonical`] into [`Any`].
576    /// - [`Canonical`] into [`Absolute`].
577    /// - Any form into itself.
578    ///
579    /// # Examples
580    ///
581    /// ```
582    /// use nu_path::{Path, RelativePath};
583    ///
584    /// let relative = RelativePath::try_new("test.txt").unwrap();
585    /// let p: &Path = relative.cast();
586    /// assert_eq!(p, relative);
587    /// ```
588    #[inline]
589    pub fn cast<To>(&self) -> &Path<To>
590    where
591        To: PathForm,
592        Form: PathCast<To>,
593    {
594        Path::new_unchecked(self)
595    }
596
597    /// Returns a reference to a path with its form as [`Any`].
598    ///
599    /// # Examples
600    ///
601    /// ```
602    /// use nu_path::{Path, RelativePath};
603    ///
604    /// let p = RelativePath::try_new("test.txt").unwrap();
605    /// assert_eq!(Path::new("test.txt"), p.as_any());
606    /// ```
607    #[inline]
608    pub fn as_any(&self) -> &Path {
609        Path::new_unchecked(self)
610    }
611}
612
613impl Path {
614    /// Create a new [`Path`] by wrapping a string slice.
615    ///
616    /// This is a cost-free conversion.
617    ///
618    /// # Examples
619    ///
620    /// ```
621    /// use nu_path::Path;
622    ///
623    /// Path::new("foo.txt");
624    /// ```
625    ///
626    /// You can create [`Path`]s from [`String`]s, or even other [`Path`]s:
627    ///
628    /// ```
629    /// use nu_path::Path;
630    ///
631    /// let string = String::from("foo.txt");
632    /// let from_string = Path::new(&string);
633    /// let from_path = Path::new(&from_string);
634    /// assert_eq!(from_string, from_path);
635    /// ```
636    #[inline]
637    pub fn new<P: AsRef<OsStr> + ?Sized>(path: &P) -> &Self {
638        Self::new_unchecked(path)
639    }
640
641    /// Returns a mutable reference to the underlying [`OsStr`] slice.
642    ///
643    /// # Examples
644    ///
645    /// ```
646    /// use nu_path::{Path, PathBuf};
647    ///
648    /// let mut path = PathBuf::from("Foo.TXT");
649    ///
650    /// assert_ne!(path, Path::new("foo.txt"));
651    ///
652    /// path.as_mut_os_str().make_ascii_lowercase();
653    /// assert_eq!(path, Path::new("foo.txt"));
654    /// ```
655    #[must_use]
656    #[inline]
657    pub fn as_mut_os_str(&mut self) -> &mut OsStr {
658        self.inner.as_mut_os_str()
659    }
660
661    /// Returns `true` if the [`Path`] is absolute, i.e., if it is independent of
662    /// the current directory.
663    ///
664    /// * On Unix, a path is absolute if it starts with the root,
665    ///   so [`is_absolute`](Path::is_absolute) and [`has_root`](Path::has_root) are equivalent.
666    ///
667    /// * On Windows, a path is absolute if it has a prefix and starts with the root:
668    ///   `c:\windows` is absolute, while `c:temp` and `\temp` are not.
669    ///
670    /// # Examples
671    ///
672    /// ```
673    /// use nu_path::Path;
674    ///
675    /// assert!(!Path::new("foo.txt").is_absolute());
676    /// ```
677    #[must_use]
678    #[inline]
679    pub fn is_absolute(&self) -> bool {
680        self.inner.is_absolute()
681    }
682
683    // Returns `true` if the [`Path`] is relative, i.e., not absolute.
684    ///
685    /// See [`is_absolute`](Path::is_absolute)'s documentation for more details.
686    ///
687    /// # Examples
688    ///
689    /// ```
690    /// use nu_path::Path;
691    ///
692    /// assert!(Path::new("foo.txt").is_relative());
693    /// ```
694    #[must_use]
695    #[inline]
696    pub fn is_relative(&self) -> bool {
697        self.inner.is_relative()
698    }
699
700    /// Returns an `Ok` [`AbsolutePath`] if the [`Path`] is absolute.
701    /// Otherwise, returns an `Err` [`RelativePath`].
702    ///
703    /// # Examples
704    ///
705    /// ```
706    /// use nu_path::Path;
707    ///
708    /// assert!(Path::new("test.txt").try_absolute().is_err());
709    /// ```
710    #[inline]
711    pub fn try_absolute(&self) -> Result<&AbsolutePath, &RelativePath> {
712        if self.is_absolute() {
713            Ok(AbsolutePath::new_unchecked(&self.inner))
714        } else {
715            Err(RelativePath::new_unchecked(&self.inner))
716        }
717    }
718
719    /// Returns an `Ok` [`RelativePath`] if the [`Path`] is relative.
720    /// Otherwise, returns an `Err` [`AbsolutePath`].
721    ///
722    /// # Examples
723    ///
724    /// ```
725    /// use nu_path::Path;
726    ///
727    /// assert!(Path::new("test.txt").try_relative().is_ok());
728    /// ```
729    #[inline]
730    pub fn try_relative(&self) -> Result<&RelativePath, &AbsolutePath> {
731        if self.is_relative() {
732            Ok(RelativePath::new_unchecked(&self.inner))
733        } else {
734            Err(AbsolutePath::new_unchecked(&self.inner))
735        }
736    }
737}
738
739impl<Form: PathJoin> Path<Form> {
740    /// Creates an owned [`PathBuf`] with `path` adjoined to `self`.
741    ///
742    /// If `path` is absolute, it replaces the current path.
743    ///
744    /// See [`PathBuf::push`] for more details on what it means to adjoin a path.
745    ///
746    /// # Examples
747    ///
748    /// ```
749    /// use nu_path::{Path, PathBuf};
750    ///
751    /// assert_eq!(Path::new("/etc").join("passwd"), PathBuf::from("/etc/passwd"));
752    /// assert_eq!(Path::new("/etc").join("/bin/sh"), PathBuf::from("/bin/sh"));
753    /// ```
754    #[must_use]
755    #[inline]
756    pub fn join(&self, path: impl AsRef<Path>) -> PathBuf<Form::Output> {
757        PathBuf::new_unchecked(self.inner.join(&path.as_ref().inner))
758    }
759}
760
761impl<Form: PathSet> Path<Form> {
762    /// Creates an owned [`PathBuf`] like `self` but with the given file name.
763    ///
764    /// See [`PathBuf::set_file_name`] for more details.
765    ///
766    /// # Examples
767    ///
768    /// ```
769    /// use nu_path::{Path, PathBuf};
770    ///
771    /// let path = Path::new("/tmp/foo.png");
772    /// assert_eq!(path.with_file_name("bar"), PathBuf::from("/tmp/bar"));
773    /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt"));
774    ///
775    /// let path = Path::new("/tmp");
776    /// assert_eq!(path.with_file_name("var"), PathBuf::from("/var"));
777    /// ```
778    #[inline]
779    pub fn with_file_name(&self, file_name: impl AsRef<OsStr>) -> PathBuf<Form> {
780        PathBuf::new_unchecked(self.inner.with_file_name(file_name))
781    }
782
783    /// Creates an owned [`PathBuf`] like `self` but with the given extension.
784    ///
785    /// See [`PathBuf::set_extension`] for more details.
786    ///
787    /// # Examples
788    ///
789    /// ```
790    /// use nu_path::{Path, PathBuf};
791    ///
792    /// let path = Path::new("foo.rs");
793    /// assert_eq!(path.with_extension("txt"), PathBuf::from("foo.txt"));
794    ///
795    /// let path = Path::new("foo.tar.gz");
796    /// assert_eq!(path.with_extension(""), PathBuf::from("foo.tar"));
797    /// assert_eq!(path.with_extension("xz"), PathBuf::from("foo.tar.xz"));
798    /// assert_eq!(path.with_extension("").with_extension("txt"), PathBuf::from("foo.txt"));
799    /// ```
800    #[inline]
801    pub fn with_extension(&self, extension: impl AsRef<OsStr>) -> PathBuf<Form> {
802        PathBuf::new_unchecked(self.inner.with_extension(extension))
803    }
804}
805
806impl<Form: MaybeRelative> Path<Form> {
807    /// Returns the, potentially relative, underlying [`std::path::Path`].
808    ///
809    /// # Note
810    ///
811    /// Caution should be taken when using this function. Nushell keeps track of an emulated current
812    /// working directory, and using the [`std::path::Path`] returned from this method will likely
813    /// use [`std::env::current_dir`] to resolve the path instead of using the emulated current
814    /// working directory.
815    ///
816    /// Instead, you should probably join this path onto the emulated current working directory.
817    /// Any [`AbsolutePath`] or [`CanonicalPath`] will also suffice.
818    ///
819    /// # Examples
820    ///
821    /// ```
822    /// use nu_path::Path;
823    ///
824    /// let p = Path::new("test.txt");
825    /// assert_eq!(std::path::Path::new("test.txt"), p.as_relative_std_path());
826    /// ```
827    #[inline]
828    pub fn as_relative_std_path(&self) -> &std::path::Path {
829        &self.inner
830    }
831
832    // Returns `true` if the [`Path`] has a root.
833    ///
834    /// * On Unix, a path has a root if it begins with `/`.
835    ///
836    /// * On Windows, a path has a root if it:
837    ///     * has no prefix and begins with a separator, e.g., `\windows`
838    ///     * has a prefix followed by a separator, e.g., `c:\windows` but not `c:windows`
839    ///     * has any non-disk prefix, e.g., `\\server\share`
840    ///
841    /// # Examples
842    ///
843    /// ```
844    /// use nu_path::Path;
845    ///
846    /// assert!(Path::new("/etc/passwd").has_root());
847    /// ```
848    #[must_use]
849    #[inline]
850    pub fn has_root(&self) -> bool {
851        self.inner.has_root()
852    }
853}
854
855impl<Form: IsAbsolute> Path<Form> {
856    /// Returns the underlying [`std::path::Path`].
857    ///
858    /// # Examples
859    ///
860    #[cfg_attr(not(windows), doc = "```")]
861    #[cfg_attr(windows, doc = "```no_run")]
862    /// use nu_path::AbsolutePath;
863    ///
864    /// let p = AbsolutePath::try_new("/test").unwrap();
865    /// assert_eq!(std::path::Path::new("/test"), p.as_std_path());
866    /// ```
867    #[inline]
868    pub fn as_std_path(&self) -> &std::path::Path {
869        &self.inner
870    }
871
872    /// Converts a [`Path`] to an owned [`std::path::PathBuf`].
873    ///
874    /// # Examples
875    ///
876    #[cfg_attr(not(windows), doc = "```")]
877    #[cfg_attr(windows, doc = "```no_run")]
878    /// use nu_path::AbsolutePath;
879    ///
880    /// let path = AbsolutePath::try_new("/foo").unwrap();
881    /// assert_eq!(path.to_std_path_buf(), std::path::PathBuf::from("/foo"));
882    /// ```
883    #[inline]
884    pub fn to_std_path_buf(&self) -> std::path::PathBuf {
885        self.inner.to_path_buf()
886    }
887
888    /// Queries the file system to get information about a file, directory, etc.
889    ///
890    /// This function will traverse symbolic links to query information about the destination file.
891    ///
892    /// This is an alias to [`std::fs::metadata`].
893    ///
894    /// # Examples
895    ///
896    /// ```no_run
897    /// use nu_path::AbsolutePath;
898    ///
899    /// let path = AbsolutePath::try_new("/Minas/tirith").unwrap();
900    /// let metadata = path.metadata().expect("metadata call failed");
901    /// println!("{:?}", metadata.file_type());
902    /// ```
903    #[inline]
904    pub fn metadata(&self) -> io::Result<fs::Metadata> {
905        self.inner.metadata()
906    }
907
908    /// Returns an iterator over the entries within a directory.
909    ///
910    /// The iterator will yield instances of <code>[io::Result]<[fs::DirEntry]></code>.
911    /// New errors may be encountered after an iterator is initially constructed.
912    ///
913    /// This is an alias to [`std::fs::read_dir`].
914    ///
915    /// # Examples
916    ///
917    /// ```no_run
918    /// use nu_path::AbsolutePath;
919    ///
920    /// let path = AbsolutePath::try_new("/laputa").unwrap();
921    /// for entry in path.read_dir().expect("read_dir call failed") {
922    ///     if let Ok(entry) = entry {
923    ///         println!("{:?}", entry.path());
924    ///     }
925    /// }
926    /// ```
927    #[inline]
928    pub fn read_dir(&self) -> io::Result<fs::ReadDir> {
929        self.inner.read_dir()
930    }
931
932    /// Returns `true` if the path points at an existing entity.
933    ///
934    /// Warning: this method may be error-prone, consider using [`try_exists`](Path::try_exists)
935    /// instead! It also has a risk of introducing time-of-check to time-of-use (TOCTOU) bugs.
936    ///
937    /// This function will traverse symbolic links to query information about the destination file.
938    ///
939    /// If you cannot access the metadata of the file, e.g. because of a permission error
940    /// or broken symbolic links, this will return `false`.
941    ///
942    /// # Examples
943    ///
944    /// ```no_run
945    /// use nu_path::AbsolutePath;
946    ///
947    /// let path = AbsolutePath::try_new("/does_not_exist").unwrap();
948    /// assert!(!path.exists());
949    /// ```
950    #[must_use]
951    #[inline]
952    pub fn exists(&self) -> bool {
953        self.inner.exists()
954    }
955
956    /// Returns `true` if the path exists on disk and is pointing at a regular file.
957    ///
958    /// This function will traverse symbolic links to query information about the destination file.
959    ///
960    /// If you cannot access the metadata of the file, e.g. because of a permission error
961    /// or broken symbolic links, this will return `false`.
962    ///
963    /// # Examples
964    ///
965    /// ```no_run
966    /// use nu_path::AbsolutePath;
967    ///
968    /// let path = AbsolutePath::try_new("/is_a_directory/").unwrap();
969    /// assert_eq!(path.is_file(), false);
970    ///
971    /// let path = AbsolutePath::try_new("/a_file.txt").unwrap();
972    /// assert_eq!(path.is_file(), true);
973    /// ```
974    ///
975    /// # See Also
976    ///
977    /// When the goal is simply to read from (or write to) the source, the most reliable way
978    /// to test the source can be read (or written to) is to open it. Only using `is_file` can
979    /// break workflows like `diff <( prog_a )` on a Unix-like system for example.
980    /// See [`std::fs::File::open`] or [`std::fs::OpenOptions::open`] for more information.
981    #[must_use]
982    #[inline]
983    pub fn is_file(&self) -> bool {
984        self.inner.is_file()
985    }
986
987    /// Returns `true` if the path exists on disk and is pointing at a directory.
988    ///
989    /// This function will traverse symbolic links to query information about the destination file.
990    ///
991    /// If you cannot access the metadata of the file, e.g. because of a permission error
992    /// or broken symbolic links, this will return `false`.
993    ///
994    /// # Examples
995    ///
996    /// ```no_run
997    /// use nu_path::AbsolutePath;
998    ///
999    /// let path = AbsolutePath::try_new("/is_a_directory/").unwrap();
1000    /// assert_eq!(path.is_dir(), true);
1001    ///
1002    /// let path = AbsolutePath::try_new("/a_file.txt").unwrap();
1003    /// assert_eq!(path.is_dir(), false);
1004    /// ```
1005    #[must_use]
1006    #[inline]
1007    pub fn is_dir(&self) -> bool {
1008        self.inner.is_dir()
1009    }
1010}
1011
1012impl AbsolutePath {
1013    /// Returns the canonical, absolute form of the path with all intermediate components
1014    /// normalized and symbolic links resolved.
1015    ///
1016    /// On Windows, this will also simplify to a winuser path.
1017    ///
1018    /// This is an alias to [`std::fs::canonicalize`].
1019    ///
1020    /// # Examples
1021    ///
1022    /// ```no_run
1023    /// use nu_path::{AbsolutePath, PathBuf};
1024    ///
1025    /// let path = AbsolutePath::try_new("/foo/test/../test/bar.rs").unwrap();
1026    /// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs"));
1027    /// ```
1028    #[cfg(not(windows))]
1029    #[inline]
1030    pub fn canonicalize(&self) -> io::Result<CanonicalPathBuf> {
1031        self.inner
1032            .canonicalize()
1033            .map(CanonicalPathBuf::new_unchecked)
1034    }
1035
1036    /// Returns the canonical, absolute form of the path with all intermediate components
1037    /// normalized and symbolic links resolved.
1038    ///
1039    /// On Windows, this will also simplify to a winuser path.
1040    ///
1041    /// This is an alias to [`std::fs::canonicalize`].
1042    ///
1043    /// # Examples
1044    ///
1045    /// ```no_run
1046    /// use nu_path::{AbsolutePath, PathBuf};
1047    ///
1048    /// let path = AbsolutePath::try_new("/foo/test/../test/bar.rs").unwrap();
1049    /// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs"));
1050    /// ```
1051    #[cfg(windows)]
1052    pub fn canonicalize(&self) -> io::Result<CanonicalPathBuf> {
1053        use omnipath::WinPathExt;
1054
1055        let path = self.inner.canonicalize()?.to_winuser_path()?;
1056        Ok(CanonicalPathBuf::new_unchecked(path))
1057    }
1058
1059    /// Reads a symbolic link, returning the file that the link points to.
1060    ///
1061    /// This is an alias to [`std::fs::read_link`].
1062    ///
1063    /// # Examples
1064    ///
1065    /// ```no_run
1066    /// use nu_path::AbsolutePath;
1067    ///
1068    /// let path = AbsolutePath::try_new("/laputa/sky_castle.rs").unwrap();
1069    /// let path_link = path.read_link().expect("read_link call failed");
1070    /// ```
1071    #[inline]
1072    pub fn read_link(&self) -> io::Result<AbsolutePathBuf> {
1073        self.inner.read_link().map(PathBuf::new_unchecked)
1074    }
1075
1076    /// Returns `Ok(true)` if the path points at an existing entity.
1077    ///
1078    /// This function will traverse symbolic links to query information about the destination file.
1079    /// In case of broken symbolic links this will return `Ok(false)`.
1080    ///
1081    /// [`Path::exists`] only checks whether or not a path was both found and readable.
1082    /// By contrast, [`try_exists`](Path::try_exists) will return `Ok(true)` or `Ok(false)`,
1083    /// respectively, if the path was _verified_ to exist or not exist.
1084    /// If its existence can neither be confirmed nor denied, it will propagate an `Err` instead.
1085    /// This can be the case if e.g. listing permission is denied on one of the parent directories.
1086    ///
1087    /// Note that while this avoids some pitfalls of the [`exists`](Path::exists) method,
1088    /// it still can not prevent time-of-check to time-of-use (TOCTOU) bugs.
1089    /// You should only use it in scenarios where those bugs are not an issue.
1090    ///
1091    /// # Examples
1092    ///
1093    /// ```no_run
1094    /// use nu_path::AbsolutePath;
1095    ///
1096    /// let path = AbsolutePath::try_new("/does_not_exist").unwrap();
1097    /// assert!(!path.try_exists().unwrap());
1098    ///
1099    /// let path = AbsolutePath::try_new("/root/secret_file.txt").unwrap();
1100    /// assert!(path.try_exists().is_err());
1101    /// ```
1102    #[inline]
1103    pub fn try_exists(&self) -> io::Result<bool> {
1104        self.inner.try_exists()
1105    }
1106
1107    /// Returns `true` if the path exists on disk and is pointing at a symbolic link.
1108    ///
1109    /// This function will not traverse symbolic links.
1110    /// In case of a broken symbolic link this will also return true.
1111    ///
1112    /// If you cannot access the directory containing the file, e.g., because of a permission error,
1113    /// this will return false.
1114    ///
1115    /// # Examples
1116    ///
1117    #[cfg_attr(unix, doc = "```no_run")]
1118    #[cfg_attr(not(unix), doc = "```ignore")]
1119    /// use nu_path::AbsolutePath;
1120    /// use std::os::unix::fs::symlink;
1121    ///
1122    /// let link_path = AbsolutePath::try_new("/link").unwrap();
1123    /// symlink("/origin_does_not_exist/", link_path).unwrap();
1124    /// assert_eq!(link_path.is_symlink(), true);
1125    /// assert_eq!(link_path.exists(), false);
1126    /// ```
1127    #[must_use]
1128    #[inline]
1129    pub fn is_symlink(&self) -> bool {
1130        self.inner.is_symlink()
1131    }
1132
1133    /// Queries the metadata about a file without following symlinks.
1134    ///
1135    /// This is an alias to [`std::fs::symlink_metadata`].
1136    ///
1137    /// # Examples
1138    ///
1139    /// ```no_run
1140    /// use nu_path::AbsolutePath;
1141    ///
1142    /// let path = AbsolutePath::try_new("/Minas/tirith").unwrap();
1143    /// let metadata = path.symlink_metadata().expect("symlink_metadata call failed");
1144    /// println!("{:?}", metadata.file_type());
1145    /// ```
1146    #[inline]
1147    pub fn symlink_metadata(&self) -> io::Result<fs::Metadata> {
1148        self.inner.symlink_metadata()
1149    }
1150}
1151
1152impl CanonicalPath {
1153    /// Returns a [`CanonicalPath`] as a [`AbsolutePath`].
1154    ///
1155    /// # Examples
1156    ///
1157    /// ```no_run
1158    /// use nu_path::AbsolutePath;
1159    ///
1160    /// let absolute = AbsolutePath::try_new("/test").unwrap();
1161    /// let p = absolute.canonicalize().unwrap();
1162    /// assert_eq!(absolute, p.as_absolute());
1163    /// ```
1164    #[inline]
1165    pub fn as_absolute(&self) -> &AbsolutePath {
1166        self.cast()
1167    }
1168}
1169
1170impl<Form: PathForm> fmt::Debug for Path<Form> {
1171    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1172        fmt::Debug::fmt(&self.inner, fmt)
1173    }
1174}
1175
1176impl<Form: PathForm> Clone for Box<Path<Form>> {
1177    #[inline]
1178    fn clone(&self) -> Self {
1179        std_box_to_box(self.inner.into())
1180    }
1181}
1182
1183impl<Form: PathForm> ToOwned for Path<Form> {
1184    type Owned = PathBuf<Form>;
1185
1186    #[inline]
1187    fn to_owned(&self) -> Self::Owned {
1188        self.to_path_buf()
1189    }
1190
1191    #[inline]
1192    fn clone_into(&self, target: &mut PathBuf<Form>) {
1193        self.inner.clone_into(&mut target.inner);
1194    }
1195}
1196
1197impl<'a, Form: PathForm> IntoIterator for &'a Path<Form> {
1198    type Item = &'a OsStr;
1199
1200    type IntoIter = std::path::Iter<'a>;
1201
1202    #[inline]
1203    fn into_iter(self) -> Self::IntoIter {
1204        self.iter()
1205    }
1206}
1207
1208/// An iterator over [`Path`] and its ancestors.
1209///
1210/// This `struct` is created by the [`ancestors`](Path::ancestors) method on [`Path`].
1211/// See its documentation for more.
1212///
1213/// # Examples
1214///
1215/// ```
1216/// use nu_path::Path;
1217///
1218/// let path = Path::new("/foo/bar");
1219///
1220/// for ancestor in path.ancestors() {
1221///     println!("{}", ancestor.display());
1222/// }
1223/// ```
1224#[derive(Clone, Copy)]
1225pub struct Ancestors<'a, Form: PathForm> {
1226    _form: PhantomData<Form>,
1227    inner: std::path::Ancestors<'a>,
1228}
1229
1230impl<Form: PathForm> fmt::Debug for Ancestors<'_, Form> {
1231    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1232        fmt::Debug::fmt(&self.inner, f)
1233    }
1234}
1235
1236impl<'a, Form: PathForm> Iterator for Ancestors<'a, Form> {
1237    type Item = &'a Path<Form>;
1238
1239    fn next(&mut self) -> Option<Self::Item> {
1240        self.inner.next().map(Path::new_unchecked)
1241    }
1242}
1243
1244impl<Form: PathForm> FusedIterator for Ancestors<'_, Form> {}
1245
1246/// A wrapper around [`std::path::PathBuf`] with extra invariants determined by its `Form`.
1247///
1248/// The possible path forms are [`Any`], [`Relative`], [`Absolute`], or [`Canonical`].
1249/// To learn more, view the documentation on [`PathForm`] or any of the individual forms.
1250///
1251/// There are also several type aliases available, corresponding to each [`PathForm`]:
1252/// - [`RelativePathBuf`] (same as [`PathBuf<Relative>`])
1253/// - [`AbsolutePathBuf`] (same as [`PathBuf<Absolute>`])
1254/// - [`CanonicalPathBuf`] (same as [`PathBuf<Canonical>`])
1255///
1256/// If the `Form` is not specified, then it defaults to [`Any`],
1257/// so [`PathBuf`] and [`PathBuf<Any>`] are one in the same.
1258///
1259/// # Examples
1260///
1261/// To create a [`PathBuf`] with [`Any`] form, you can use the same techniques as when creating
1262/// a [`std::path::PathBuf`].
1263///
1264/// ```
1265/// use nu_path::PathBuf;
1266///
1267/// let path = PathBuf::from(r"C:\windows\system32.dll");
1268///
1269/// let mut path1 = PathBuf::new();
1270/// path1.push(r"C:\");
1271/// path1.push("windows");
1272/// path1.push("system32");
1273/// path1.set_extension("dll");
1274///
1275/// let path2: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
1276///
1277/// assert_eq!(path1, path2);
1278/// ```
1279///
1280/// # Converting to [`std::path`] types
1281///
1282/// [`PathBuf`]s with form [`Any`] cannot be easily referenced as a [`std::path::Path`]
1283/// or converted to a [`std::path::PathBuf`] by design.
1284/// Other Nushell crates need to account for the emulated current working directory
1285/// before passing a path to functions in [`std`] or other third party crates.
1286/// You can [`join`](Path::join) a [`Path`] onto an [`AbsolutePath`] or a [`CanonicalPath`].
1287/// This will return an [`AbsolutePathBuf`] which can be easily referenced as a [`std::path::Path`].
1288/// If you really mean it, you can instead use [`as_relative_std_path`](Path::as_relative_std_path)
1289/// or [`into_relative_std_path_buf`](PathBuf::into_relative_std_path_buf)
1290/// to get the underlying [`std::path::Path`] or [`std::path::PathBuf`] from a [`PathBuf`].
1291/// But this may cause third-party code to use [`std::env::current_dir`] to resolve
1292/// the path which is almost always incorrect behavior. Extra care is needed to ensure that this
1293/// is not the case after using [`as_relative_std_path`](Path::as_relative_std_path)
1294/// or [`into_relative_std_path_buf`](PathBuf::into_relative_std_path_buf).
1295#[repr(transparent)]
1296pub struct PathBuf<Form: PathForm = Any> {
1297    _form: PhantomData<Form>,
1298    inner: std::path::PathBuf,
1299}
1300
1301/// A path buf that is strictly relative.
1302///
1303/// I.e., this path buf is guaranteed to never be absolute.
1304///
1305/// [`RelativePathBuf`]s cannot be easily referenced as a [`std::path::Path`]
1306/// or converted to a [`std::path::PathBuf`] by design.
1307/// Other Nushell crates need to account for the emulated current working directory
1308/// before passing a path to functions in [`std`] or other third party crates.
1309/// You can [`join`](Path::join) a [`RelativePath`] onto an [`AbsolutePath`] or a [`CanonicalPath`].
1310/// This will return an [`AbsolutePathBuf`] which can be easily referenced as a [`std::path::Path`].
1311/// If you really mean it, you can instead use
1312/// [`as_relative_std_path`](RelativePath::as_relative_std_path)
1313/// or [`into_relative_std_path_buf`](RelativePathBuf::into_relative_std_path_buf)
1314/// to get the underlying [`std::path::Path`] or [`std::path::PathBuf`] from a [`RelativePathBuf`].
1315/// But this may cause third-party code to use [`std::env::current_dir`] to resolve
1316/// the path which is almost always incorrect behavior. Extra care is needed to ensure that this
1317/// is not the case after using [`as_relative_std_path`](RelativePath::as_relative_std_path)
1318/// or [`into_relative_std_path_buf`](RelativePathBuf::into_relative_std_path_buf).
1319///
1320/// # Examples
1321///
1322/// [`RelativePathBuf`]s can be created by using [`try_into_relative`](PathBuf::try_into_relative)
1323/// on a [`PathBuf`] or by using [`to_path_buf`](Path::to_path_buf) on a [`RelativePath`].
1324///
1325/// ```
1326/// use nu_path::{PathBuf, RelativePath, RelativePathBuf};
1327///
1328/// let path_buf = PathBuf::from("foo.txt");
1329/// let path_buf = path_buf.try_into_relative().unwrap();
1330///
1331/// let path = RelativePath::try_new("foo.txt").unwrap();
1332/// let path_buf2 = path.to_path_buf();
1333///
1334/// assert_eq!(path_buf, path_buf2);
1335/// ```
1336///
1337/// You can also use `RelativePathBuf::try_from` or `try_into`.
1338/// This supports attempted conversions from [`Path`] as well as types in [`std::path`].
1339///
1340/// ```
1341/// use nu_path::{Path, RelativePathBuf};
1342///
1343/// let path1 = RelativePathBuf::try_from("foo.txt").unwrap();
1344///
1345/// let path2 = Path::new("foo.txt");
1346/// let path2 = RelativePathBuf::try_from(path2).unwrap();
1347///
1348/// let path3 = std::path::PathBuf::from("foo.txt");
1349/// let path3: RelativePathBuf = path3.try_into().unwrap();
1350///
1351/// assert_eq!(path1, path2);
1352/// assert_eq!(path2, path3);
1353/// ```
1354pub type RelativePathBuf = PathBuf<Relative>;
1355
1356/// A path buf that is strictly absolute.
1357///
1358/// I.e., this path buf is guaranteed to never be relative.
1359///
1360/// # Examples
1361///
1362/// [`AbsolutePathBuf`]s can be created by using [`try_into_absolute`](PathBuf::try_into_absolute)
1363/// on a [`PathBuf`] or by using [`to_path_buf`](Path::to_path_buf) on an [`AbsolutePath`].
1364///
1365#[cfg_attr(not(windows), doc = "```")]
1366#[cfg_attr(windows, doc = "```no_run")]
1367/// use nu_path::{AbsolutePath, AbsolutePathBuf, PathBuf};
1368///
1369/// let path_buf1 = PathBuf::from("/foo");
1370/// let path_buf1 = path_buf1.try_into_absolute().unwrap();
1371///
1372/// let path = AbsolutePath::try_new("/foo").unwrap();
1373/// let path_buf2 = path.to_path_buf();
1374///
1375/// assert_eq!(path_buf1, path_buf2);
1376/// ```
1377///
1378/// You can also use `AbsolutePathBuf::try_from` or `try_into`.
1379/// This supports attempted conversions from [`Path`] as well as types in [`std::path`].
1380///
1381#[cfg_attr(not(windows), doc = "```")]
1382#[cfg_attr(windows, doc = "```no_run")]
1383/// use nu_path::{AbsolutePathBuf, Path};
1384///
1385/// let path1 = AbsolutePathBuf::try_from("/foo").unwrap();
1386///
1387/// let path2 = Path::new("/foo");
1388/// let path2 = AbsolutePathBuf::try_from(path2).unwrap();
1389///
1390/// let path3 = std::path::PathBuf::from("/foo");
1391/// let path3: AbsolutePathBuf = path3.try_into().unwrap();
1392///
1393/// assert_eq!(path1, path2);
1394/// assert_eq!(path2, path3);
1395/// ```
1396pub type AbsolutePathBuf = PathBuf<Absolute>;
1397
1398/// An absolute, canonical path buf.
1399///
1400/// # Examples
1401///
1402/// [`CanonicalPathBuf`]s can only be created by using [`canonicalize`](Path::canonicalize) on
1403/// an [`AbsolutePath`]. [`CanonicalPathBuf`]s can be converted back to [`AbsolutePathBuf`]s via
1404/// [`into_absolute`](CanonicalPathBuf::into_absolute).
1405///
1406/// ```no_run
1407/// use nu_path::AbsolutePathBuf;
1408///
1409/// let path = AbsolutePathBuf::try_from("/foo").unwrap();
1410///
1411/// let canonical = path.canonicalize().expect("canonicalization failed");
1412///
1413/// assert_eq!(path, canonical.into_absolute());
1414/// ```
1415pub type CanonicalPathBuf = PathBuf<Canonical>;
1416
1417impl<Form: PathForm> PathBuf<Form> {
1418    /// Create a new [`PathBuf`] of any form without validiting invariants.
1419    #[inline]
1420    pub(crate) fn new_unchecked(buf: std::path::PathBuf) -> Self {
1421        debug_assert!(Form::invariants_satisfied(&buf));
1422        Self {
1423            _form: PhantomData,
1424            inner: buf,
1425        }
1426    }
1427
1428    /// Coerces to a [`Path`] slice.
1429    ///
1430    /// # Examples
1431    ///
1432    /// ```
1433    /// use nu_path::{Path, PathBuf};
1434    ///
1435    /// let p = PathBuf::from("/test");
1436    /// assert_eq!(Path::new("/test"), p.as_path());
1437    /// ```
1438    #[must_use]
1439    #[inline]
1440    pub fn as_path(&self) -> &Path<Form> {
1441        Path::new_unchecked(&self.inner)
1442    }
1443
1444    /// Truncates `self` to [`self.parent`](Path::parent).
1445    ///
1446    /// Returns `false` and does nothing if [`self.parent`](Path::parent) is [`None`].
1447    /// Otherwise, returns `true`.
1448    ///
1449    /// # Examples
1450    ///
1451    /// ```
1452    /// use nu_path::{Path, PathBuf};
1453    ///
1454    /// let mut p = PathBuf::from("/spirited/away.rs");
1455    ///
1456    /// p.pop();
1457    /// assert_eq!(Path::new("/spirited"), p);
1458    /// p.pop();
1459    /// assert_eq!(Path::new("/"), p);
1460    /// ```
1461    #[inline]
1462    pub fn pop(&mut self) -> bool {
1463        self.inner.pop()
1464    }
1465
1466    /// Consumes the [`PathBuf`], returning its internal [`OsString`] storage.
1467    ///
1468    /// # Examples
1469    ///
1470    /// ```
1471    /// use nu_path::PathBuf;
1472    ///
1473    /// let p = PathBuf::from("/the/head");
1474    /// let os_str = p.into_os_string();
1475    /// ```
1476    #[inline]
1477    pub fn into_os_string(self) -> OsString {
1478        self.inner.into_os_string()
1479    }
1480
1481    /// Converts this [`PathBuf`] into a [boxed](Box) [`Path`].
1482    #[inline]
1483    pub fn into_boxed_path(self) -> Box<Path<Form>> {
1484        std_box_to_box(self.inner.into_boxed_path())
1485    }
1486
1487    /// Returns the [`capacity`](OsString::capacity) of the underlying [`OsString`].
1488    #[must_use]
1489    #[inline]
1490    pub fn capacity(&self) -> usize {
1491        self.inner.capacity()
1492    }
1493
1494    /// Invokes [`reserve`](OsString::reserve) on the underlying [`OsString`].
1495    #[inline]
1496    pub fn reserve(&mut self, additional: usize) {
1497        self.inner.reserve(additional)
1498    }
1499
1500    /// Invokes [`try_reserve`](OsString::try_reserve) on the underlying [`OsString`].
1501    #[inline]
1502    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
1503        self.inner.try_reserve(additional)
1504    }
1505
1506    /// Invokes [`reserve_exact`](OsString::reserve_exact) on the underlying [`OsString`].
1507    #[inline]
1508    pub fn reserve_exact(&mut self, additional: usize) {
1509        self.inner.reserve_exact(additional)
1510    }
1511
1512    /// Invokes [`try_reserve_exact`](OsString::try_reserve_exact) on the underlying [`OsString`].
1513    #[inline]
1514    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
1515        self.inner.try_reserve_exact(additional)
1516    }
1517
1518    /// Invokes [`shrink_to_fit`](OsString::shrink_to_fit) on the underlying [`OsString`].
1519    #[inline]
1520    pub fn shrink_to_fit(&mut self) {
1521        self.inner.shrink_to_fit()
1522    }
1523
1524    /// Invokes [`shrink_to`](OsString::shrink_to) on the underlying [`OsString`].
1525    #[inline]
1526    pub fn shrink_to(&mut self, min_capacity: usize) {
1527        self.inner.shrink_to(min_capacity)
1528    }
1529
1530    /// Consumes a [`PathBuf`], returning it with a different form.
1531    ///
1532    /// [`PathForm`]s can be converted to one another based on [`PathCast`] implementations.
1533    /// Namely, the following form conversions are possible:
1534    /// - [`Relative`], [`Absolute`], or [`Canonical`] into [`Any`].
1535    /// - [`Canonical`] into [`Absolute`].
1536    /// - Any form into itself.
1537    ///
1538    /// # Examples
1539    ///
1540    /// ```
1541    /// use nu_path::{PathBuf, RelativePathBuf};
1542    ///
1543    /// let p = RelativePathBuf::try_from("test.txt").unwrap();
1544    /// let p: PathBuf = p.cast_into();
1545    /// assert_eq!(PathBuf::from("test.txt"), p);
1546    /// ```
1547    #[inline]
1548    pub fn cast_into<To>(self) -> PathBuf<To>
1549    where
1550        To: PathForm,
1551        Form: PathCast<To>,
1552    {
1553        PathBuf::new_unchecked(self.inner)
1554    }
1555
1556    /// Consumes a [`PathBuf`], returning it with form [`Any`].
1557    ///
1558    /// # Examples
1559    ///
1560    /// ```
1561    /// use nu_path::{PathBuf, RelativePathBuf};
1562    ///
1563    /// let p = RelativePathBuf::try_from("test.txt").unwrap();
1564    /// assert_eq!(PathBuf::from("test.txt"), p.into_any());
1565    /// ```
1566    #[inline]
1567    pub fn into_any(self) -> PathBuf {
1568        PathBuf::new_unchecked(self.inner)
1569    }
1570}
1571
1572impl PathBuf {
1573    /// Creates an empty [`PathBuf`].
1574    ///
1575    /// # Examples
1576    ///
1577    /// ```
1578    /// use nu_path::PathBuf;
1579    ///
1580    /// let path = PathBuf::new();
1581    /// ```
1582    #[must_use]
1583    #[inline]
1584    pub fn new() -> Self {
1585        Self::new_unchecked(std::path::PathBuf::new())
1586    }
1587
1588    /// Creates a new [`PathBuf`] with a given capacity used to create the internal [`OsString`].
1589    /// See [`with_capacity`](OsString::with_capacity) defined on [`OsString`].
1590    ///
1591    /// # Examples
1592    ///
1593    /// ```
1594    /// use nu_path::PathBuf;
1595    ///
1596    /// let mut path = PathBuf::with_capacity(10);
1597    /// let capacity = path.capacity();
1598    ///
1599    /// // This push is done without reallocating
1600    /// path.push(r"C:\");
1601    ///
1602    /// assert_eq!(capacity, path.capacity());
1603    /// ```
1604    #[inline]
1605    #[must_use]
1606    pub fn with_capacity(capacity: usize) -> Self {
1607        Self::new_unchecked(std::path::PathBuf::with_capacity(capacity))
1608    }
1609
1610    /// Returns a mutable reference to the underlying [`OsString`].
1611    ///
1612    /// # Examples
1613    ///
1614    /// ```
1615    /// use nu_path::{Path, PathBuf};
1616    ///
1617    /// let mut path = PathBuf::from("/foo");
1618    ///
1619    /// path.push("bar");
1620    /// assert_eq!(path, Path::new("/foo/bar"));
1621    ///
1622    /// // OsString's `push` does not add a separator.
1623    /// path.as_mut_os_string().push("baz");
1624    /// assert_eq!(path, Path::new("/foo/barbaz"));
1625    /// ```
1626    #[must_use]
1627    #[inline]
1628    pub fn as_mut_os_string(&mut self) -> &mut OsString {
1629        self.inner.as_mut_os_string()
1630    }
1631
1632    /// Invokes [`clear`](OsString::clear) on the underlying [`OsString`].
1633    #[inline]
1634    pub fn clear(&mut self) {
1635        self.inner.clear()
1636    }
1637
1638    /// Consumes a [`PathBuf`], returning an `Ok` [`RelativePathBuf`] if the [`PathBuf`]
1639    /// is relative. Otherwise, returns the original [`PathBuf`] as an `Err`.
1640    ///
1641    /// # Examples
1642    ///
1643    /// ```
1644    /// use nu_path::PathBuf;
1645    ///
1646    /// assert!(PathBuf::from("test.txt").try_into_relative().is_ok());
1647    /// ```
1648    #[inline]
1649    pub fn try_into_relative(self) -> Result<RelativePathBuf, Self> {
1650        if self.inner.is_relative() {
1651            Ok(PathBuf::new_unchecked(self.inner))
1652        } else {
1653            Err(self)
1654        }
1655    }
1656
1657    /// Consumes a [`PathBuf`], returning an `Ok` [`AbsolutePathBuf`] if the [`PathBuf`]
1658    /// is absolute. Otherwise, returns the original [`PathBuf`] as an `Err`.
1659    ///
1660    /// # Examples
1661    ///
1662    /// ```
1663    /// use nu_path::PathBuf;
1664    ///
1665    /// assert!(PathBuf::from("test.txt").try_into_absolute().is_err());
1666    /// ```
1667    #[inline]
1668    pub fn try_into_absolute(self) -> Result<AbsolutePathBuf, Self> {
1669        if self.inner.is_absolute() {
1670            Ok(PathBuf::new_unchecked(self.inner))
1671        } else {
1672            Err(self)
1673        }
1674    }
1675}
1676
1677impl<Form: PathPush> PathBuf<Form> {
1678    /// Extends `self` with `path`.
1679    ///
1680    /// If `path` is absolute, it replaces the current path.
1681    ///
1682    /// On Windows:
1683    ///
1684    /// * if `path` has a root but no prefix (e.g., `\windows`), it
1685    ///   replaces everything except for the prefix (if any) of `self`.
1686    /// * if `path` has a prefix but no root, it replaces `self`.
1687    /// * if `self` has a verbatim prefix (e.g. `\\?\C:\windows`)
1688    ///   and `path` is not empty, the new path is normalized: all references
1689    ///   to `.` and `..` are removed.
1690    ///
1691    /// Consider using [`Path::join`] if you need a new [`PathBuf`] instead of
1692    /// using this function on a cloned [`PathBuf`].
1693    ///
1694    /// # Examples
1695    ///
1696    /// Pushing a relative path extends the existing path:
1697    ///
1698    /// ```
1699    /// use nu_path::PathBuf;
1700    ///
1701    /// let mut path = PathBuf::from("/tmp");
1702    /// path.push("file.bk");
1703    /// assert_eq!(path, PathBuf::from("/tmp/file.bk"));
1704    /// ```
1705    ///
1706    /// Pushing an absolute path replaces the existing path:
1707    ///
1708    /// ```
1709    /// use nu_path::PathBuf;
1710    ///
1711    /// let mut path = PathBuf::from("/tmp");
1712    /// path.push("/etc");
1713    /// assert_eq!(path, PathBuf::from("/etc"));
1714    /// ```
1715    #[inline]
1716    pub fn push(&mut self, path: impl AsRef<Path>) {
1717        self.inner.push(&path.as_ref().inner)
1718    }
1719}
1720
1721impl<Form: PathSet> PathBuf<Form> {
1722    /// Updates [`self.file_name`](Path::file_name) to `file_name`.
1723    ///
1724    /// If [`self.file_name`](Path::file_name) was [`None`],
1725    /// this is equivalent to pushing `file_name`.
1726    ///
1727    /// Otherwise it is equivalent to calling [`pop`](PathBuf::pop) and then pushing `file_name`.
1728    /// The new path will be a sibling of the original path.
1729    /// (That is, it will have the same parent.)
1730    ///
1731    /// # Examples
1732    ///
1733    /// ```
1734    /// use nu_path::PathBuf;
1735    ///
1736    /// let mut buf = PathBuf::from("/");
1737    /// assert!(buf.file_name() == None);
1738    ///
1739    /// buf.set_file_name("foo.txt");
1740    /// assert!(buf == PathBuf::from("/foo.txt"));
1741    /// assert!(buf.file_name().is_some());
1742    ///
1743    /// buf.set_file_name("bar.txt");
1744    /// assert!(buf == PathBuf::from("/bar.txt"));
1745    ///
1746    /// buf.set_file_name("baz");
1747    /// assert!(buf == PathBuf::from("/baz"));
1748    /// ```
1749    #[inline]
1750    pub fn set_file_name(&mut self, file_name: impl AsRef<OsStr>) {
1751        self.inner.set_file_name(file_name)
1752    }
1753
1754    /// Updates [`self.extension`](Path::extension) to `Some(extension)` or to [`None`] if
1755    /// `extension` is empty.
1756    ///
1757    /// Returns `false` and does nothing if [`self.file_name`](Path::file_name) is [`None`],
1758    /// returns `true` and updates the extension otherwise.
1759    ///
1760    /// If [`self.extension`](Path::extension) is [`None`], the extension is added; otherwise
1761    /// it is replaced.
1762    ///
1763    /// If `extension` is the empty string, [`self.extension`](Path::extension) will be [`None`]
1764    /// afterwards, not `Some("")`.
1765    ///
1766    /// # Caveats
1767    ///
1768    /// The new `extension` may contain dots and will be used in its entirety,
1769    /// but only the part after the final dot will be reflected in
1770    /// [`self.extension`](Path::extension).
1771    ///
1772    /// If the file stem contains internal dots and `extension` is empty, part of the
1773    /// old file stem will be considered the new [`self.extension`](Path::extension).
1774    ///
1775    /// # Examples
1776    ///
1777    /// ```
1778    /// use nu_path::{Path, PathBuf};
1779    ///
1780    /// let mut p = PathBuf::from("/feel/the");
1781    ///
1782    /// p.set_extension("force");
1783    /// assert_eq!(Path::new("/feel/the.force"), p.as_path());
1784    ///
1785    /// p.set_extension("dark.side");
1786    /// assert_eq!(Path::new("/feel/the.dark.side"), p.as_path());
1787    ///
1788    /// p.set_extension("cookie");
1789    /// assert_eq!(Path::new("/feel/the.dark.cookie"), p.as_path());
1790    ///
1791    /// p.set_extension("");
1792    /// assert_eq!(Path::new("/feel/the.dark"), p.as_path());
1793    ///
1794    /// p.set_extension("");
1795    /// assert_eq!(Path::new("/feel/the"), p.as_path());
1796    ///
1797    /// p.set_extension("");
1798    /// assert_eq!(Path::new("/feel/the"), p.as_path());
1799    /// ```
1800    #[inline]
1801    pub fn set_extension(&mut self, extension: impl AsRef<OsStr>) -> bool {
1802        self.inner.set_extension(extension)
1803    }
1804}
1805
1806impl<Form: MaybeRelative> PathBuf<Form> {
1807    /// Consumes a [`PathBuf`] and returns the, potentially relative,
1808    /// underlying [`std::path::PathBuf`].
1809    ///
1810    /// # Note
1811    ///
1812    /// Caution should be taken when using this function. Nushell keeps track of an emulated current
1813    /// working directory, and using the [`std::path::PathBuf`] returned from this method
1814    /// will likely use [`std::env::current_dir`] to resolve the path instead of
1815    /// using the emulated current working directory.
1816    ///
1817    /// Instead, you should probably join this path onto the emulated current working directory.
1818    /// Any [`AbsolutePath`] or [`CanonicalPath`] will also suffice.
1819    ///
1820    /// # Examples
1821    ///
1822    /// ```
1823    /// use nu_path::PathBuf;
1824    ///
1825    /// let p = PathBuf::from("test.txt");
1826    /// assert_eq!(std::path::PathBuf::from("test.txt"), p.into_relative_std_path_buf());
1827    /// ```
1828    #[inline]
1829    pub fn into_relative_std_path_buf(self) -> std::path::PathBuf {
1830        self.inner
1831    }
1832}
1833
1834impl<Form: IsAbsolute> PathBuf<Form> {
1835    /// Consumes a [`PathBuf`] and returns the underlying [`std::path::PathBuf`].
1836    ///
1837    /// # Examples
1838    ///
1839    #[cfg_attr(not(windows), doc = "```")]
1840    #[cfg_attr(windows, doc = "```no_run")]
1841    /// use nu_path::AbsolutePathBuf;
1842    ///
1843    /// let p = AbsolutePathBuf::try_from("/test").unwrap();
1844    /// assert_eq!(std::path::PathBuf::from("/test"), p.into_std_path_buf());
1845    /// ```
1846    #[inline]
1847    pub fn into_std_path_buf(self) -> std::path::PathBuf {
1848        self.inner
1849    }
1850}
1851
1852impl CanonicalPathBuf {
1853    /// Consumes a [`CanonicalPathBuf`] and returns an [`AbsolutePathBuf`].
1854    ///
1855    /// # Examples
1856    ///
1857    /// ```no_run
1858    /// use nu_path::AbsolutePathBuf;
1859    ///
1860    /// let absolute = AbsolutePathBuf::try_from("/test").unwrap();
1861    /// let p = absolute.canonicalize().unwrap();
1862    /// assert_eq!(absolute, p.into_absolute());
1863    /// ```
1864    #[inline]
1865    pub fn into_absolute(self) -> AbsolutePathBuf {
1866        self.cast_into()
1867    }
1868}
1869
1870impl Default for PathBuf {
1871    #[inline]
1872    fn default() -> Self {
1873        Self::new()
1874    }
1875}
1876
1877impl<Form: PathForm> Clone for PathBuf<Form> {
1878    #[inline]
1879    fn clone(&self) -> Self {
1880        Self {
1881            _form: PhantomData,
1882            inner: self.inner.clone(),
1883        }
1884    }
1885}
1886
1887impl<Form: PathForm> fmt::Debug for PathBuf<Form> {
1888    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1889        fmt::Debug::fmt(&**self, f)
1890    }
1891}
1892
1893impl<Form: PathForm> Deref for PathBuf<Form> {
1894    type Target = Path<Form>;
1895
1896    #[inline]
1897    fn deref(&self) -> &Self::Target {
1898        self.as_path()
1899    }
1900}
1901
1902impl DerefMut for PathBuf {
1903    #[inline]
1904    fn deref_mut(&mut self) -> &mut Self::Target {
1905        #[ref_cast_custom]
1906        fn ref_cast<Form: PathForm>(path: &mut std::path::Path) -> &mut Path<Form>;
1907
1908        ref_cast(&mut self.inner)
1909    }
1910}
1911
1912impl<From: PathCast<To>, To: PathForm> Borrow<Path<To>> for PathBuf<From> {
1913    #[inline]
1914    fn borrow(&self) -> &Path<To> {
1915        self.cast()
1916    }
1917}
1918
1919impl<Form: IsAbsolute> Borrow<std::path::Path> for PathBuf<Form> {
1920    #[inline]
1921    fn borrow(&self) -> &std::path::Path {
1922        self.as_ref()
1923    }
1924}
1925
1926impl Borrow<Path> for std::path::PathBuf {
1927    #[inline]
1928    fn borrow(&self) -> &Path {
1929        self.as_ref()
1930    }
1931}
1932
1933impl FromStr for PathBuf {
1934    type Err = Infallible;
1935
1936    #[inline]
1937    fn from_str(s: &str) -> Result<Self, Self::Err> {
1938        Ok(s.into())
1939    }
1940}
1941
1942impl FromStr for RelativePathBuf {
1943    type Err = TryRelativeError;
1944
1945    #[inline]
1946    fn from_str(s: &str) -> Result<Self, Self::Err> {
1947        s.try_into()
1948    }
1949}
1950
1951impl FromStr for AbsolutePathBuf {
1952    type Err = TryAbsoluteError;
1953
1954    #[inline]
1955    fn from_str(s: &str) -> Result<Self, Self::Err> {
1956        s.try_into()
1957    }
1958}
1959
1960impl<P: AsRef<Path>> Extend<P> for PathBuf {
1961    fn extend<T: IntoIterator<Item = P>>(&mut self, iter: T) {
1962        for path in iter {
1963            self.push(path);
1964        }
1965    }
1966}
1967
1968impl<P: AsRef<Path>> FromIterator<P> for PathBuf {
1969    fn from_iter<T: IntoIterator<Item = P>>(iter: T) -> Self {
1970        let mut buf = Self::new_unchecked(std::path::PathBuf::new());
1971        buf.extend(iter);
1972        buf
1973    }
1974}
1975
1976impl<'a, Form: PathForm> IntoIterator for &'a PathBuf<Form> {
1977    type Item = &'a OsStr;
1978
1979    type IntoIter = std::path::Iter<'a>;
1980
1981    #[inline]
1982    fn into_iter(self) -> Self::IntoIter {
1983        self.iter()
1984    }
1985}
1986
1987#[inline]
1988fn box_to_box_unchecked<From: PathForm, To: PathForm>(path: Box<Path<From>>) -> Box<Path<To>> {
1989    // Safety: `Path<From>` and `Path<To>` differ only by PhantomData tag.
1990    let ptr = Box::into_raw(path) as *mut Path<To>;
1991    unsafe { Box::from_raw(ptr) }
1992}
1993
1994#[inline]
1995fn std_box_to_box<Form: PathForm>(path: Box<std::path::Path>) -> Box<Path<Form>> {
1996    // Safety: `Path<From>` is a repr(transparent) wrapper around `std::path::Path`.
1997    let ptr = Box::into_raw(path) as *mut Path<Form>;
1998    unsafe { Box::from_raw(ptr) }
1999}
2000
2001#[inline]
2002fn std_arc_to_arc<Form: PathForm>(path: Arc<std::path::Path>) -> Arc<Path<Form>> {
2003    // Safety: `Path<From>` is a repr(transparent) wrapper around `std::path::Path`.
2004    let ptr = Arc::into_raw(path) as *mut Path<Form>;
2005    unsafe { Arc::from_raw(ptr) }
2006}
2007
2008#[inline]
2009fn std_rc_to_rc<Form: PathForm>(path: Rc<std::path::Path>) -> Rc<Path<Form>> {
2010    // Safety: `Path<From>` is a repr(transparent) wrapper around `std::path::Path`.
2011    let ptr = Rc::into_raw(path) as *mut Path<Form>;
2012    unsafe { Rc::from_raw(ptr) }
2013}
2014
2015/*
2016================================================================================
2017  AsRef
2018================================================================================
2019*/
2020
2021// Here we match all `AsRef` implementations on `std::path::Path` and `std::path::PathBuf`,
2022// adding casting variations where possible.
2023
2024macro_rules! impl_as_ref {
2025    ([$($from:ty),* $(,)?] => $to:ty |$self:ident| $cast:block) => {
2026        $(
2027            impl AsRef<$to> for $from {
2028                #[inline]
2029                fn as_ref(&$self) -> &$to $cast
2030            }
2031        )*
2032    };
2033}
2034
2035// === To and from crate types ===
2036
2037impl<From: PathCast<To>, To: PathForm> AsRef<Path<To>> for Path<From> {
2038    #[inline]
2039    fn as_ref(&self) -> &Path<To> {
2040        self.cast()
2041    }
2042}
2043
2044impl<From: PathCast<To>, To: PathForm> AsRef<Path<To>> for PathBuf<From> {
2045    #[inline]
2046    fn as_ref(&self) -> &Path<To> {
2047        self.cast()
2048    }
2049}
2050
2051impl_as_ref!(
2052    [
2053        Box<RelativePath>, Box<AbsolutePath>, Box<CanonicalPath>,
2054        Cow<'_, RelativePath>, Cow<'_, AbsolutePath>, Cow<'_, CanonicalPath>,
2055        Rc<RelativePath>, Rc<AbsolutePath>, Rc<CanonicalPath>,
2056        Arc<RelativePath>, Arc<AbsolutePath>, Arc<CanonicalPath>,
2057    ]
2058    => Path |self| { self.cast() }
2059);
2060
2061impl_as_ref!(
2062    [Box<CanonicalPath>, Cow<'_, CanonicalPath>, Rc<CanonicalPath>, Arc<CanonicalPath>]
2063    => AbsolutePath |self| { self.cast() }
2064);
2065
2066// === To and from std::path types ===
2067
2068impl<Form: IsAbsolute> AsRef<std::path::Path> for Path<Form> {
2069    #[inline]
2070    fn as_ref(&self) -> &std::path::Path {
2071        self.as_std_path()
2072    }
2073}
2074
2075impl<Form: IsAbsolute> AsRef<std::path::Path> for PathBuf<Form> {
2076    #[inline]
2077    fn as_ref(&self) -> &std::path::Path {
2078        self.as_std_path()
2079    }
2080}
2081
2082impl_as_ref!(
2083    [std::path::Path, std::path::PathBuf, std::path::Component<'_>]
2084    => Path |self| { Path::new(self) }
2085);
2086
2087impl_as_ref!(
2088    [Box<std::path::Path>, Cow<'_, std::path::Path>, Rc<std::path::Path>, Arc<std::path::Path>]
2089    => Path |self| { Path::new(self.as_os_str()) }
2090);
2091
2092// === To and from string types ===
2093
2094impl<Form: PathForm> AsRef<OsStr> for Path<Form> {
2095    #[inline]
2096    fn as_ref(&self) -> &OsStr {
2097        self.as_os_str()
2098    }
2099}
2100
2101impl<Form: PathForm> AsRef<OsStr> for PathBuf<Form> {
2102    #[inline]
2103    fn as_ref(&self) -> &OsStr {
2104        self.as_os_str()
2105    }
2106}
2107
2108impl_as_ref!([OsStr, OsString, Cow<'_, OsStr>, str, String] => Path |self| { Path::new(self) });
2109
2110/*
2111================================================================================
2112  From
2113================================================================================
2114*/
2115
2116// Here we match all `From` implementations on `std::path::Path` and `std::path::PathBuf`,
2117// adding casting variations where possible.
2118
2119macro_rules! impl_from {
2120    ([$($from:ty),* $(,)?] => $to:ty |$value:ident| $convert:block) => {
2121        $(
2122            impl From<$from> for $to {
2123                #[inline]
2124                fn from($value: $from) -> Self $convert
2125            }
2126        )*
2127    };
2128    (<$form:ident> $from:ty => $to:ty |$value:ident| $convert:block) => {
2129        impl<$form: PathForm> From<$from> for $to {
2130            #[inline]
2131            fn from($value: $from) -> Self $convert
2132        }
2133    };
2134}
2135
2136macro_rules! impl_into_std {
2137    (<$form:ident> $from:ty => [$($to:ty),* $(,)?] |$value:ident| $convert:block) => {
2138        $(
2139            impl<$form: IsAbsolute> From<$from> for $to {
2140                #[inline]
2141                fn from($value: $from) -> Self $convert
2142            }
2143        )*
2144    };
2145}
2146
2147// ===== Owned to Owned =====
2148
2149// === To and from crate types ===
2150
2151impl_from!([RelativePathBuf, AbsolutePathBuf, CanonicalPathBuf] => PathBuf
2152    |buf| { buf.cast_into() }
2153);
2154impl_from!([CanonicalPathBuf] => AbsolutePathBuf |buf| { buf.cast_into() });
2155
2156#[inline]
2157fn box_to_box<From: PathCast<To>, To: PathForm>(path: Box<Path<From>>) -> Box<Path<To>> {
2158    box_to_box_unchecked(path)
2159}
2160impl_from!([Box<RelativePath>, Box<AbsolutePath>, Box<CanonicalPath>] => Box<Path>
2161    |path| { box_to_box(path) }
2162);
2163impl_from!([Box<CanonicalPath>] => Box<AbsolutePath> |path| { box_to_box(path) });
2164
2165impl_from!(<Form> PathBuf<Form> => Box<Path<Form>> |buf| { buf.into_boxed_path() });
2166impl_from!([RelativePathBuf, AbsolutePathBuf, CanonicalPathBuf] => Box<Path>
2167    |buf| { buf.into_boxed_path().into() }
2168);
2169impl_from!([CanonicalPathBuf] => Box<AbsolutePath> |buf| { buf.into_boxed_path().into() });
2170
2171impl_from!(<Form> Box<Path<Form>> => PathBuf<Form> |path| { path.into_path_buf() });
2172impl_from!([Box<RelativePath>, Box<AbsolutePath>, Box<CanonicalPath>] => PathBuf
2173    |path| { path.into_path_buf().into() }
2174);
2175impl_from!([Box<CanonicalPath>] => AbsolutePathBuf |path| { path.into_path_buf().into() });
2176
2177impl_from!(<Form> PathBuf<Form> => Cow<'_, Path<Form>> |buf| { Self::Owned(buf) });
2178impl_from!([RelativePathBuf, AbsolutePathBuf, CanonicalPathBuf] => Cow<'_, Path>
2179    |buf| { Self::Owned(buf.into()) }
2180);
2181impl_from!([CanonicalPathBuf] => Cow<'_, AbsolutePath> |buf| { Self::Owned(buf.into()) });
2182
2183impl_from!(<Form> Cow<'_, Path<Form>> => PathBuf<Form> |cow| { cow.into_owned() });
2184impl_from!([Cow<'_, RelativePath>, Cow<'_, AbsolutePath>, Cow<'_, CanonicalPath>] => PathBuf
2185    |cow| { cow.into_owned().into() }
2186);
2187impl_from!([Cow<'_, CanonicalPath>] => AbsolutePathBuf |cow| { cow.into_owned().into() });
2188
2189#[inline]
2190fn cow_to_box<From, To>(cow: Cow<'_, From>) -> Box<To>
2191where
2192    From: ?Sized + ToOwned,
2193    for<'a> &'a From: Into<Box<To>>,
2194    From::Owned: Into<Box<To>>,
2195    To: ?Sized,
2196{
2197    match cow {
2198        Cow::Borrowed(path) => path.into(),
2199        Cow::Owned(path) => path.into(),
2200    }
2201}
2202impl_from!(<Form> Cow<'_, Path<Form>> => Box<Path<Form>> |cow| { cow_to_box(cow) });
2203impl_from!([Cow<'_, RelativePath>, Cow<'_, AbsolutePath>, Cow<'_, CanonicalPath>] => Box<Path>
2204    |cow| { cow_to_box(cow) }
2205);
2206impl_from!([Cow<'_, CanonicalPath>] => Box<AbsolutePath> |cow| { cow_to_box(cow) });
2207
2208#[inline]
2209fn buf_to_arc<From: PathCast<To>, To: PathForm>(buf: PathBuf<From>) -> Arc<Path<To>> {
2210    std_arc_to_arc(buf.inner.into())
2211}
2212impl_from!(<Form> PathBuf<Form> => Arc<Path<Form>> |buf| { buf_to_arc(buf) });
2213impl_from!([RelativePathBuf, AbsolutePathBuf, CanonicalPathBuf] => Arc<Path>
2214    |buf| { buf_to_arc(buf) }
2215);
2216impl_from!([CanonicalPathBuf] => Arc<AbsolutePath> |buf| { buf_to_arc(buf) });
2217
2218#[inline]
2219fn buf_to_rc<From: PathCast<To>, To: PathForm>(buf: PathBuf<From>) -> Rc<Path<To>> {
2220    std_rc_to_rc(buf.inner.into())
2221}
2222impl_from!(<Form> PathBuf<Form> => Rc<Path<Form>> |buf| { buf_to_rc(buf) });
2223impl_from!([RelativePathBuf, AbsolutePathBuf, CanonicalPathBuf] => Rc<Path>
2224    |buf| { buf_to_rc(buf) }
2225);
2226impl_from!([CanonicalPathBuf] => Rc<AbsolutePath> |buf| { buf_to_rc(buf) });
2227
2228// === To and from std::path types ===
2229
2230impl_into_std!(<Form> PathBuf<Form> => [std::path::PathBuf] |buf| { buf.inner });
2231impl_into_std!(
2232    <Form> PathBuf<Form> => [
2233        Box<std::path::Path>, Cow<'_, std::path::Path>, Arc<std::path::Path>, Rc<std::path::Path>
2234    ]
2235    |buf| { buf.inner.into() }
2236);
2237impl_into_std!(<Form> Box<Path<Form>> => [std::path::PathBuf, Box<std::path::Path>]
2238    |path| { path.inner.into() }
2239);
2240
2241impl_from!([std::path::PathBuf] => PathBuf |buf| { Self::new_unchecked(buf) });
2242impl_from!([Box<std::path::Path>] => PathBuf |path| { Self::new_unchecked(path.into()) });
2243impl_from!([Cow<'_, std::path::Path>] => PathBuf |cow| { Self::new_unchecked(cow.into()) });
2244
2245impl From<Box<std::path::Path>> for Box<Path> {
2246    #[inline]
2247    fn from(path: Box<std::path::Path>) -> Self {
2248        std_box_to_box(path)
2249    }
2250}
2251impl_from!([std::path::PathBuf] => Box<Path> |buf| { buf.into_boxed_path().into() });
2252impl_from!([Cow<'_, std::path::Path>] => Box<Path> |cow| { cow_to_box(cow) });
2253
2254// === To and from string types ===
2255
2256impl_from!(<Form> PathBuf<Form> => OsString |buf| { buf.inner.into() });
2257impl_from!([OsString, String] => PathBuf |s| { Self::new_unchecked(s.into()) });
2258
2259// ===== Borrowed to Owned =====
2260
2261// === To and from crate types ===
2262// Here we also add casting conversions from `T: impl AsRef<Path<Form>>` to `PathBuf<Form>`.
2263
2264impl<Source: PathCast<To>, To: PathForm> From<&Path<Source>> for Box<Path<To>> {
2265    #[inline]
2266    fn from(path: &Path<Source>) -> Self {
2267        std_box_to_box(path.inner.into())
2268    }
2269}
2270
2271impl<'a, Source: PathCast<To>, To: PathForm> From<&'a Path<Source>> for Cow<'a, Path<To>> {
2272    #[inline]
2273    fn from(path: &'a Path<Source>) -> Self {
2274        path.cast().into()
2275    }
2276}
2277
2278impl<'a, Source: PathCast<To>, To: PathForm> From<&'a PathBuf<Source>> for Cow<'a, Path<To>> {
2279    #[inline]
2280    fn from(buf: &'a PathBuf<Source>) -> Self {
2281        buf.cast().into()
2282    }
2283}
2284
2285impl<Source: PathCast<To>, To: PathForm> From<&Path<Source>> for Arc<Path<To>> {
2286    #[inline]
2287    fn from(path: &Path<Source>) -> Self {
2288        std_arc_to_arc(path.inner.into())
2289    }
2290}
2291
2292impl<Source: PathCast<To>, To: PathForm> From<&Path<Source>> for Rc<Path<To>> {
2293    #[inline]
2294    fn from(path: &Path<Source>) -> Self {
2295        std_rc_to_rc(path.inner.into())
2296    }
2297}
2298
2299impl<T: ?Sized + AsRef<RelativePath>> From<&T> for RelativePathBuf {
2300    #[inline]
2301    fn from(s: &T) -> Self {
2302        Self::new_unchecked(s.as_ref().into())
2303    }
2304}
2305
2306impl<T: ?Sized + AsRef<AbsolutePath>> From<&T> for AbsolutePathBuf {
2307    #[inline]
2308    fn from(s: &T) -> Self {
2309        Self::new_unchecked(s.as_ref().into())
2310    }
2311}
2312
2313impl<T: ?Sized + AsRef<CanonicalPath>> From<&T> for CanonicalPathBuf {
2314    #[inline]
2315    fn from(s: &T) -> Self {
2316        Self::new_unchecked(s.as_ref().into())
2317    }
2318}
2319
2320// === To and from std::path types ===
2321
2322impl_into_std!(
2323    <Form> &Path<Form> => [Box<std::path::Path>, Arc<std::path::Path>, Rc<std::path::Path>]
2324    |path| { path.inner.into() }
2325);
2326
2327impl<'a, Form: IsAbsolute> From<&'a Path<Form>> for Cow<'a, std::path::Path> {
2328    #[inline]
2329    fn from(path: &'a Path<Form>) -> Self {
2330        path.inner.into()
2331    }
2332}
2333
2334impl<'a, Form: IsAbsolute> From<&'a PathBuf<Form>> for Cow<'a, std::path::Path> {
2335    #[inline]
2336    fn from(buf: &'a PathBuf<Form>) -> Self {
2337        Self::Borrowed(buf.as_ref())
2338    }
2339}
2340
2341impl_from!([&std::path::Path] => Box<Path> |path| { Path::new(path).into() });
2342
2343// === To and from string types ===
2344
2345impl<T: ?Sized + AsRef<OsStr>> From<&T> for PathBuf {
2346    #[inline]
2347    fn from(s: &T) -> Self {
2348        Self::new_unchecked(s.as_ref().into())
2349    }
2350}
2351
2352/*
2353================================================================================
2354  TryFrom
2355================================================================================
2356*/
2357
2358#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2359pub struct TryRelativeError;
2360
2361impl fmt::Display for TryRelativeError {
2362    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2363        write!(fmt, "path was not a relative path")
2364    }
2365}
2366
2367#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2368pub struct TryAbsoluteError;
2369
2370impl fmt::Display for TryAbsoluteError {
2371    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2372        write!(fmt, "path was not an absolute path")
2373    }
2374}
2375
2376// ===== Borrowed to borrowed =====
2377// Here we match all `AsRef` implementations on `std::path::Path`.
2378
2379macro_rules! impl_try_from_borrowed_to_borrowed {
2380    ([$($from:ty),* $(,)?], |$value:ident| $convert:block $(,)?) => {
2381        $(
2382            impl<'a> TryFrom<&'a $from> for &'a RelativePath {
2383                type Error = TryRelativeError;
2384
2385                #[inline]
2386                fn try_from($value: &'a $from) -> Result<Self, Self::Error> $convert
2387            }
2388
2389            impl<'a> TryFrom<&'a $from> for &'a AbsolutePath {
2390                type Error = TryAbsoluteError;
2391
2392                #[inline]
2393                fn try_from($value: &'a $from) -> Result<Self, Self::Error> $convert
2394            }
2395        )*
2396    };
2397}
2398
2399// === From crate types ===
2400
2401impl<'a> TryFrom<&'a Path> for &'a RelativePath {
2402    type Error = TryRelativeError;
2403
2404    #[inline]
2405    fn try_from(path: &'a Path) -> Result<Self, Self::Error> {
2406        path.try_relative().map_err(|_| TryRelativeError)
2407    }
2408}
2409
2410impl<'a> TryFrom<&'a Path> for &'a AbsolutePath {
2411    type Error = TryAbsoluteError;
2412
2413    #[inline]
2414    fn try_from(path: &'a Path) -> Result<Self, Self::Error> {
2415        path.try_absolute().map_err(|_| TryAbsoluteError)
2416    }
2417}
2418
2419impl_try_from_borrowed_to_borrowed!([PathBuf], |buf| { Path::new(buf).try_into() });
2420
2421// === From std::path types ===
2422
2423impl_try_from_borrowed_to_borrowed!([std::path::Path], |path| { Path::new(path).try_into() });
2424impl_try_from_borrowed_to_borrowed!([std::path::PathBuf], |buf| { Path::new(buf).try_into() });
2425impl_try_from_borrowed_to_borrowed!([std::path::Component<'_>], |component| {
2426    Path::new(component).try_into()
2427});
2428impl_try_from_borrowed_to_borrowed!([std::path::Components<'_>], |components| {
2429    Path::new(components).try_into()
2430});
2431impl_try_from_borrowed_to_borrowed!([std::path::Iter<'_>], |iter| { Path::new(iter).try_into() });
2432
2433// === From string types ===
2434
2435impl_try_from_borrowed_to_borrowed!(
2436    [OsStr, OsString, Cow<'_, OsStr>, str, String],
2437    |s| { Path::new(s).try_into() },
2438);
2439
2440// ===== Borrowed to Owned =====
2441// Here we match all `From<&T>` implementations on `std::path::Path` and `std::path::PathBuf`.
2442// Note that to match `From<&T: AsRef<OsStr>>` on `std::path::PathBuf`,
2443// we add string conversions and a few others.
2444
2445macro_rules! impl_try_from_borrowed_to_owned {
2446    ([$($from:ty),* $(,)?] => $rel:ty, $abs:ty $(,)?) => {
2447        $(
2448            impl TryFrom<&$from> for $rel {
2449                type Error = TryRelativeError;
2450
2451                #[inline]
2452                fn try_from(path: &$from) -> Result<Self, Self::Error> {
2453                    let path: &RelativePath = path.try_into()?;
2454                    Ok(path.into())
2455                }
2456            }
2457
2458            impl TryFrom<&$from> for $abs {
2459                type Error = TryAbsoluteError;
2460
2461                #[inline]
2462                fn try_from(path: &$from) -> Result<Self, Self::Error> {
2463                    let path: &AbsolutePath = path.try_into()?;
2464                    Ok(path.into())
2465                }
2466            }
2467        )*
2468    };
2469    (<$life:lifetime> $from:ty => $rel:ty, $abs:ty $(,)?) => {
2470        impl<$life> TryFrom<&$life $from> for $rel {
2471            type Error = TryRelativeError;
2472
2473            #[inline]
2474            fn try_from(path: &$life $from) -> Result<Self, Self::Error> {
2475                let path: &RelativePath = path.try_into()?;
2476                Ok(path.into())
2477            }
2478        }
2479
2480        impl<$life> TryFrom<&$life $from> for $abs {
2481            type Error = TryAbsoluteError;
2482
2483            #[inline]
2484            fn try_from(path: &$life $from) -> Result<Self, Self::Error> {
2485                let path: &AbsolutePath = path.try_into()?;
2486                Ok(path.into())
2487            }
2488        }
2489    };
2490}
2491
2492// === From crate types ===
2493
2494impl_try_from_borrowed_to_owned!([Path] => Box<RelativePath>, Box<AbsolutePath>);
2495impl_try_from_borrowed_to_owned!(<'a> Path => Cow<'a, RelativePath>, Cow<'a, AbsolutePath>);
2496impl_try_from_borrowed_to_owned!([Path] => Arc<RelativePath>, Arc<AbsolutePath>);
2497impl_try_from_borrowed_to_owned!([Path] => Rc<RelativePath>, Rc<AbsolutePath>);
2498
2499impl_try_from_borrowed_to_owned!([Path, PathBuf] => RelativePathBuf, AbsolutePathBuf);
2500impl_try_from_borrowed_to_owned!(<'a> PathBuf => Cow<'a, RelativePath>, Cow<'a, AbsolutePath>);
2501
2502// === From std::path types ===
2503
2504impl_try_from_borrowed_to_owned!([std::path::Path] => Box<RelativePath>, Box<AbsolutePath>);
2505
2506impl_try_from_borrowed_to_owned!(
2507    [std::path::Path, std::path::PathBuf, std::path::Component<'_>]
2508    => RelativePathBuf, AbsolutePathBuf
2509);
2510
2511// === From string types ===
2512
2513impl_try_from_borrowed_to_owned!(
2514    [OsStr, OsString, Cow<'_, OsStr>, str, String] => RelativePathBuf, AbsolutePathBuf
2515);
2516
2517// ===== Owned to Owned =====
2518// Here we match all `From<T>` implementations on `std::path::Path` and `std::path::PathBuf`
2519// where `T` is an owned type.
2520
2521// === From crate types ===
2522
2523impl TryFrom<PathBuf> for RelativePathBuf {
2524    type Error = PathBuf;
2525
2526    #[inline]
2527    fn try_from(buf: PathBuf) -> Result<Self, Self::Error> {
2528        buf.try_into_relative()
2529    }
2530}
2531
2532impl TryFrom<PathBuf> for AbsolutePathBuf {
2533    type Error = PathBuf;
2534
2535    #[inline]
2536    fn try_from(buf: PathBuf) -> Result<Self, Self::Error> {
2537        buf.try_into_absolute()
2538    }
2539}
2540
2541impl TryFrom<Box<Path>> for RelativePathBuf {
2542    type Error = Box<Path>;
2543
2544    #[inline]
2545    fn try_from(path: Box<Path>) -> Result<Self, Self::Error> {
2546        if path.is_relative() {
2547            Ok(Self::new_unchecked(path.inner.into()))
2548        } else {
2549            Err(path)
2550        }
2551    }
2552}
2553
2554impl TryFrom<Box<Path>> for AbsolutePathBuf {
2555    type Error = Box<Path>;
2556
2557    #[inline]
2558    fn try_from(path: Box<Path>) -> Result<Self, Self::Error> {
2559        if path.is_absolute() {
2560            Ok(Self::new_unchecked(path.inner.into()))
2561        } else {
2562            Err(path)
2563        }
2564    }
2565}
2566
2567impl TryFrom<Box<Path>> for Box<RelativePath> {
2568    type Error = Box<Path>;
2569
2570    #[inline]
2571    fn try_from(path: Box<Path>) -> Result<Self, Self::Error> {
2572        if path.is_relative() {
2573            Ok(box_to_box_unchecked(path))
2574        } else {
2575            Err(path)
2576        }
2577    }
2578}
2579
2580impl TryFrom<Box<Path>> for Box<AbsolutePath> {
2581    type Error = Box<Path>;
2582
2583    #[inline]
2584    fn try_from(path: Box<Path>) -> Result<Self, Self::Error> {
2585        if path.is_absolute() {
2586            Ok(box_to_box_unchecked(path))
2587        } else {
2588            Err(path)
2589        }
2590    }
2591}
2592
2593impl TryFrom<PathBuf> for Box<RelativePath> {
2594    type Error = PathBuf;
2595
2596    #[inline]
2597    fn try_from(buf: PathBuf) -> Result<Self, Self::Error> {
2598        RelativePathBuf::try_from(buf).map(Into::into)
2599    }
2600}
2601
2602impl TryFrom<PathBuf> for Box<AbsolutePath> {
2603    type Error = PathBuf;
2604
2605    #[inline]
2606    fn try_from(buf: PathBuf) -> Result<Self, Self::Error> {
2607        AbsolutePathBuf::try_from(buf).map(Into::into)
2608    }
2609}
2610
2611impl<'a> TryFrom<Cow<'a, Path>> for RelativePathBuf {
2612    type Error = Cow<'a, Path>;
2613
2614    #[inline]
2615    fn try_from(path: Cow<'a, Path>) -> Result<Self, Self::Error> {
2616        match path {
2617            Cow::Borrowed(path) => Self::try_from(path).map_err(|_| Cow::Borrowed(path)),
2618            Cow::Owned(path) => Self::try_from(path).map_err(Cow::Owned),
2619        }
2620    }
2621}
2622
2623impl<'a> TryFrom<Cow<'a, Path>> for AbsolutePathBuf {
2624    type Error = Cow<'a, Path>;
2625
2626    #[inline]
2627    fn try_from(path: Cow<'a, Path>) -> Result<Self, Self::Error> {
2628        match path {
2629            Cow::Borrowed(path) => Self::try_from(path).map_err(|_| Cow::Borrowed(path)),
2630            Cow::Owned(path) => Self::try_from(path).map_err(Cow::Owned),
2631        }
2632    }
2633}
2634
2635impl<'a> TryFrom<Cow<'a, Path>> for Box<RelativePath> {
2636    type Error = Cow<'a, Path>;
2637
2638    #[inline]
2639    fn try_from(path: Cow<'a, Path>) -> Result<Self, Self::Error> {
2640        match path {
2641            Cow::Borrowed(path) => Box::try_from(path).map_err(|_| Cow::Borrowed(path)),
2642            Cow::Owned(path) => Box::try_from(path).map_err(Cow::Owned),
2643        }
2644    }
2645}
2646
2647impl<'a> TryFrom<Cow<'a, Path>> for Box<AbsolutePath> {
2648    type Error = Cow<'a, Path>;
2649
2650    #[inline]
2651    fn try_from(path: Cow<'a, Path>) -> Result<Self, Self::Error> {
2652        match path {
2653            Cow::Borrowed(path) => Box::try_from(path).map_err(|_| Cow::Borrowed(path)),
2654            Cow::Owned(path) => Box::try_from(path).map_err(Cow::Owned),
2655        }
2656    }
2657}
2658
2659// === From std::path types ===
2660
2661impl TryFrom<std::path::PathBuf> for RelativePathBuf {
2662    type Error = std::path::PathBuf;
2663
2664    #[inline]
2665    fn try_from(buf: std::path::PathBuf) -> Result<Self, Self::Error> {
2666        Self::try_from(PathBuf::from(buf)).map_err(|buf| buf.inner)
2667    }
2668}
2669
2670impl TryFrom<std::path::PathBuf> for AbsolutePathBuf {
2671    type Error = std::path::PathBuf;
2672
2673    #[inline]
2674    fn try_from(buf: std::path::PathBuf) -> Result<Self, Self::Error> {
2675        Self::try_from(PathBuf::from(buf)).map_err(|buf| buf.inner)
2676    }
2677}
2678
2679impl TryFrom<Box<std::path::Path>> for RelativePathBuf {
2680    type Error = Box<std::path::Path>;
2681
2682    #[inline]
2683    fn try_from(path: Box<std::path::Path>) -> Result<Self, Self::Error> {
2684        if path.is_relative() {
2685            Ok(Self::new_unchecked(path.into()))
2686        } else {
2687            Err(path)
2688        }
2689    }
2690}
2691
2692impl TryFrom<Box<std::path::Path>> for AbsolutePathBuf {
2693    type Error = Box<std::path::Path>;
2694
2695    #[inline]
2696    fn try_from(path: Box<std::path::Path>) -> Result<Self, Self::Error> {
2697        if path.is_absolute() {
2698            Ok(Self::new_unchecked(path.into()))
2699        } else {
2700            Err(path)
2701        }
2702    }
2703}
2704
2705impl TryFrom<Box<std::path::Path>> for Box<RelativePath> {
2706    type Error = Box<std::path::Path>;
2707
2708    #[inline]
2709    fn try_from(path: Box<std::path::Path>) -> Result<Self, Self::Error> {
2710        if path.is_relative() {
2711            Ok(std_box_to_box(path))
2712        } else {
2713            Err(path)
2714        }
2715    }
2716}
2717
2718impl TryFrom<Box<std::path::Path>> for Box<AbsolutePath> {
2719    type Error = Box<std::path::Path>;
2720
2721    #[inline]
2722    fn try_from(path: Box<std::path::Path>) -> Result<Self, Self::Error> {
2723        if path.is_absolute() {
2724            Ok(std_box_to_box(path))
2725        } else {
2726            Err(path)
2727        }
2728    }
2729}
2730
2731impl TryFrom<std::path::PathBuf> for Box<RelativePath> {
2732    type Error = std::path::PathBuf;
2733
2734    #[inline]
2735    fn try_from(buf: std::path::PathBuf) -> Result<Self, Self::Error> {
2736        RelativePathBuf::try_from(buf).map(Into::into)
2737    }
2738}
2739
2740impl TryFrom<std::path::PathBuf> for Box<AbsolutePath> {
2741    type Error = std::path::PathBuf;
2742
2743    #[inline]
2744    fn try_from(buf: std::path::PathBuf) -> Result<Self, Self::Error> {
2745        AbsolutePathBuf::try_from(buf).map(Into::into)
2746    }
2747}
2748
2749impl<'a> TryFrom<Cow<'a, std::path::Path>> for RelativePathBuf {
2750    type Error = Cow<'a, std::path::Path>;
2751
2752    #[inline]
2753    fn try_from(path: Cow<'a, std::path::Path>) -> Result<Self, Self::Error> {
2754        match path {
2755            Cow::Borrowed(path) => Self::try_from(path).map_err(|_| Cow::Borrowed(path)),
2756            Cow::Owned(path) => Self::try_from(path).map_err(Cow::Owned),
2757        }
2758    }
2759}
2760
2761impl<'a> TryFrom<Cow<'a, std::path::Path>> for AbsolutePathBuf {
2762    type Error = Cow<'a, std::path::Path>;
2763
2764    #[inline]
2765    fn try_from(path: Cow<'a, std::path::Path>) -> Result<Self, Self::Error> {
2766        match path {
2767            Cow::Borrowed(path) => Self::try_from(path).map_err(|_| Cow::Borrowed(path)),
2768            Cow::Owned(path) => Self::try_from(path).map_err(Cow::Owned),
2769        }
2770    }
2771}
2772
2773impl<'a> TryFrom<Cow<'a, std::path::Path>> for Box<RelativePath> {
2774    type Error = Cow<'a, std::path::Path>;
2775
2776    #[inline]
2777    fn try_from(path: Cow<'a, std::path::Path>) -> Result<Self, Self::Error> {
2778        match path {
2779            Cow::Borrowed(path) => Box::try_from(path).map_err(|_| Cow::Borrowed(path)),
2780            Cow::Owned(path) => Box::try_from(path).map_err(Cow::Owned),
2781        }
2782    }
2783}
2784
2785impl<'a> TryFrom<Cow<'a, std::path::Path>> for Box<AbsolutePath> {
2786    type Error = Cow<'a, std::path::Path>;
2787
2788    #[inline]
2789    fn try_from(path: Cow<'a, std::path::Path>) -> Result<Self, Self::Error> {
2790        match path {
2791            Cow::Borrowed(path) => Box::try_from(path).map_err(|_| Cow::Borrowed(path)),
2792            Cow::Owned(path) => Box::try_from(path).map_err(Cow::Owned),
2793        }
2794    }
2795}
2796
2797// === From string types ===
2798
2799impl TryFrom<OsString> for RelativePathBuf {
2800    type Error = OsString;
2801
2802    #[inline]
2803    fn try_from(s: OsString) -> Result<Self, Self::Error> {
2804        Self::try_from(PathBuf::from(s)).map_err(|buf| buf.into_os_string())
2805    }
2806}
2807
2808impl TryFrom<OsString> for AbsolutePathBuf {
2809    type Error = OsString;
2810
2811    #[inline]
2812    fn try_from(s: OsString) -> Result<Self, Self::Error> {
2813        Self::try_from(PathBuf::from(s)).map_err(|buf| buf.into_os_string())
2814    }
2815}
2816
2817impl TryFrom<String> for RelativePathBuf {
2818    type Error = String;
2819
2820    #[inline]
2821    fn try_from(s: String) -> Result<Self, Self::Error> {
2822        if Path::new(&s).is_relative() {
2823            Ok(Self::new_unchecked(s.into()))
2824        } else {
2825            Err(s)
2826        }
2827    }
2828}
2829
2830impl TryFrom<String> for AbsolutePathBuf {
2831    type Error = String;
2832
2833    #[inline]
2834    fn try_from(s: String) -> Result<Self, Self::Error> {
2835        if Path::new(&s).is_absolute() {
2836            Ok(Self::new_unchecked(s.into()))
2837        } else {
2838            Err(s)
2839        }
2840    }
2841}
2842
2843/*
2844================================================================================
2845  PartialEq, Eq, PartialOrd, and Ord
2846================================================================================
2847*/
2848
2849// Here we match all `PartialEq` and `PartialOrd` implementations on `std::path::Path`
2850// and `std::path::PathBuf`, adding casting variations where possible.
2851
2852// === Between crate types ===
2853
2854impl<Form: PathForm> PartialEq for Path<Form> {
2855    fn eq(&self, other: &Self) -> bool {
2856        self.inner == other.inner
2857    }
2858}
2859
2860impl<Form: PathForm> Eq for Path<Form> {}
2861
2862impl<Form: PathForm> PartialOrd for Path<Form> {
2863    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2864        Some(self.cmp(other))
2865    }
2866}
2867
2868impl<Form: PathForm> Ord for Path<Form> {
2869    fn cmp(&self, other: &Self) -> Ordering {
2870        self.inner.cmp(&other.inner)
2871    }
2872}
2873
2874impl<Form: PathForm> Hash for Path<Form> {
2875    fn hash<H: Hasher>(&self, state: &mut H) {
2876        self.inner.hash(state);
2877    }
2878}
2879
2880impl<Form: PathForm> PartialEq for PathBuf<Form> {
2881    fn eq(&self, other: &Self) -> bool {
2882        self.inner == other.inner
2883    }
2884}
2885
2886impl<Form: PathForm> Eq for PathBuf<Form> {}
2887
2888impl<Form: PathForm> PartialOrd for PathBuf<Form> {
2889    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2890        Some(self.cmp(other))
2891    }
2892}
2893
2894impl<Form: PathForm> Ord for PathBuf<Form> {
2895    fn cmp(&self, other: &Self) -> Ordering {
2896        self.inner.cmp(&other.inner)
2897    }
2898}
2899
2900impl<Form: PathForm> Hash for PathBuf<Form> {
2901    fn hash<H: Hasher>(&self, state: &mut H) {
2902        self.inner.hash(state);
2903    }
2904}
2905
2906macro_rules! impl_cmp {
2907    (<$($life:lifetime),*> $lhs:ty, $rhs:ty) => {
2908        impl<$($life,)* Form: PathForm> PartialEq<$rhs> for $lhs {
2909            #[inline]
2910            fn eq(&self, other: &$rhs) -> bool {
2911                <Path<Form> as PartialEq>::eq(self, other)
2912            }
2913        }
2914
2915        impl<$($life,)* Form: PathForm> PartialEq<$lhs> for $rhs {
2916            #[inline]
2917            fn eq(&self, other: &$lhs) -> bool {
2918                <Path<Form> as PartialEq>::eq(self, other)
2919            }
2920        }
2921
2922        impl<$($life,)* Form: PathForm> PartialOrd<$rhs> for $lhs {
2923            #[inline]
2924            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
2925                <Path<Form> as PartialOrd>::partial_cmp(self, other)
2926            }
2927        }
2928
2929        impl<$($life,)* Form: PathForm> PartialOrd<$lhs> for $rhs {
2930            #[inline]
2931            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
2932                <Path<Form> as PartialOrd>::partial_cmp(self, other)
2933            }
2934        }
2935    };
2936}
2937
2938impl_cmp!(<> PathBuf<Form>, Path<Form>);
2939impl_cmp!(<'a> PathBuf<Form>, &'a Path<Form>);
2940impl_cmp!(<'a> Cow<'a, Path<Form>>, Path<Form>);
2941impl_cmp!(<'a, 'b> Cow<'a, Path<Form>>, &'b Path<Form>);
2942impl_cmp!(<'a> Cow<'a, Path<Form>>, PathBuf<Form>);
2943
2944macro_rules! impl_cmp_cast {
2945    (<$($life:lifetime),*> $lhs:ty, $rhs:ty) => {
2946        impl<$($life),*> PartialEq<$rhs> for $lhs {
2947            #[inline]
2948            fn eq(&self, other: &$rhs) -> bool {
2949                <Path as PartialEq>::eq(self.cast(), other.cast())
2950            }
2951        }
2952
2953        impl<$($life),*> PartialEq<$lhs> for $rhs {
2954            #[inline]
2955            fn eq(&self, other: &$lhs) -> bool {
2956                <Path as PartialEq>::eq(self.cast(), other.cast())
2957            }
2958        }
2959
2960        impl<$($life),*> PartialOrd<$rhs> for $lhs {
2961            #[inline]
2962            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
2963                <Path as PartialOrd>::partial_cmp(self.cast(), other.cast())
2964            }
2965        }
2966
2967        impl<$($life),*> PartialOrd<$lhs> for $rhs {
2968            #[inline]
2969            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
2970                <Path as PartialOrd>::partial_cmp(self.cast(), other.cast())
2971            }
2972        }
2973    };
2974}
2975
2976impl_cmp_cast!(<> Path, RelativePath);
2977impl_cmp_cast!(<> Path, AbsolutePath);
2978impl_cmp_cast!(<> Path, CanonicalPath);
2979impl_cmp_cast!(<> AbsolutePath, CanonicalPath);
2980impl_cmp_cast!(<> PathBuf, RelativePathBuf);
2981impl_cmp_cast!(<> PathBuf, AbsolutePathBuf);
2982impl_cmp_cast!(<> PathBuf, CanonicalPathBuf);
2983impl_cmp_cast!(<> AbsolutePathBuf, CanonicalPathBuf);
2984
2985impl_cmp_cast!(<'a> &'a Path, RelativePath);
2986impl_cmp_cast!(<'a> &'a Path, AbsolutePath);
2987impl_cmp_cast!(<'a> &'a Path, CanonicalPath);
2988impl_cmp_cast!(<'a> &'a AbsolutePath, CanonicalPath);
2989impl_cmp_cast!(<'a> Path, &'a RelativePath);
2990impl_cmp_cast!(<'a> Path, &'a AbsolutePath);
2991impl_cmp_cast!(<'a> Path, &'a CanonicalPath);
2992impl_cmp_cast!(<'a> AbsolutePath, &'a CanonicalPath);
2993
2994impl_cmp_cast!(<> PathBuf, RelativePath);
2995impl_cmp_cast!(<> PathBuf, AbsolutePath);
2996impl_cmp_cast!(<> PathBuf, CanonicalPath);
2997impl_cmp_cast!(<> AbsolutePathBuf, CanonicalPath);
2998impl_cmp_cast!(<> RelativePathBuf, Path);
2999impl_cmp_cast!(<> AbsolutePathBuf, Path);
3000impl_cmp_cast!(<> CanonicalPathBuf, Path);
3001impl_cmp_cast!(<> CanonicalPathBuf, AbsolutePath);
3002
3003impl_cmp_cast!(<'a> PathBuf, &'a RelativePath);
3004impl_cmp_cast!(<'a> PathBuf, &'a AbsolutePath);
3005impl_cmp_cast!(<'a> PathBuf, &'a CanonicalPath);
3006impl_cmp_cast!(<'a> AbsolutePathBuf, &'a CanonicalPath);
3007impl_cmp_cast!(<'a> RelativePathBuf, &'a Path);
3008impl_cmp_cast!(<'a> AbsolutePathBuf, &'a Path);
3009impl_cmp_cast!(<'a> CanonicalPathBuf, &'a Path);
3010impl_cmp_cast!(<'a> CanonicalPathBuf, &'a AbsolutePath);
3011
3012impl_cmp_cast!(<'a> Cow<'a, Path>, RelativePath);
3013impl_cmp_cast!(<'a> Cow<'a, Path>, AbsolutePath);
3014impl_cmp_cast!(<'a> Cow<'a, Path>, CanonicalPath);
3015impl_cmp_cast!(<'a> Cow<'a, AbsolutePath>, CanonicalPath);
3016impl_cmp_cast!(<'a> Cow<'a, RelativePath>, Path);
3017impl_cmp_cast!(<'a> Cow<'a, AbsolutePath>, Path);
3018impl_cmp_cast!(<'a> Cow<'a, CanonicalPath>, Path);
3019impl_cmp_cast!(<'a> Cow<'a, CanonicalPath>, AbsolutePath);
3020
3021impl_cmp_cast!(<'a, 'b> Cow<'a, Path>, &'b RelativePath);
3022impl_cmp_cast!(<'a, 'b> Cow<'a, Path>, &'b AbsolutePath);
3023impl_cmp_cast!(<'a, 'b> Cow<'a, Path>, &'b CanonicalPath);
3024impl_cmp_cast!(<'a, 'b> Cow<'a, AbsolutePath>, &'b CanonicalPath);
3025impl_cmp_cast!(<'a, 'b> Cow<'a, RelativePath>, &'b Path);
3026impl_cmp_cast!(<'a, 'b> Cow<'a, AbsolutePath>, &'b Path);
3027impl_cmp_cast!(<'a, 'b> Cow<'a, CanonicalPath>, &'b Path);
3028impl_cmp_cast!(<'a, 'b> Cow<'a, CanonicalPath>, &'b AbsolutePath);
3029
3030impl_cmp_cast!(<'a> Cow<'a, Path>, RelativePathBuf);
3031impl_cmp_cast!(<'a> Cow<'a, Path>, AbsolutePathBuf);
3032impl_cmp_cast!(<'a> Cow<'a, Path>, CanonicalPathBuf);
3033impl_cmp_cast!(<'a> Cow<'a, AbsolutePath>, CanonicalPathBuf);
3034impl_cmp_cast!(<'a> Cow<'a, RelativePath>, PathBuf);
3035impl_cmp_cast!(<'a> Cow<'a, AbsolutePath>, PathBuf);
3036impl_cmp_cast!(<'a> Cow<'a, CanonicalPath>, PathBuf);
3037impl_cmp_cast!(<'a> Cow<'a, CanonicalPath>, AbsolutePathBuf);
3038
3039// === Between std::path types ===
3040
3041macro_rules! impl_cmp_std {
3042    (<$($life:lifetime),*> $lhs:ty, $rhs:ty) => {
3043        impl<$($life,)* Form: PathForm> PartialEq<$rhs> for $lhs {
3044            #[inline]
3045            fn eq(&self, other: &$rhs) -> bool {
3046                <Path as PartialEq>::eq(self.as_ref(), other.as_any())
3047            }
3048        }
3049
3050        impl<$($life,)* Form: PathForm> PartialEq<$lhs> for $rhs {
3051            #[inline]
3052            fn eq(&self, other: &$lhs) -> bool {
3053                <Path as PartialEq>::eq(self.as_any(), other.as_ref())
3054            }
3055        }
3056
3057        impl<$($life,)* Form: PathForm> PartialOrd<$rhs> for $lhs {
3058            #[inline]
3059            fn partial_cmp(&self, other: &$rhs) -> Option<Ordering> {
3060                <Path as PartialOrd>::partial_cmp(self.as_ref(), other.as_any())
3061            }
3062        }
3063
3064        impl<$($life,)* Form: PathForm> PartialOrd<$lhs> for $rhs {
3065            #[inline]
3066            fn partial_cmp(&self, other: &$lhs) -> Option<Ordering> {
3067                <Path as PartialOrd>::partial_cmp(self.as_any(), other.as_ref())
3068            }
3069        }
3070    };
3071}
3072
3073impl_cmp_std!(<> std::path::Path, Path<Form>);
3074impl_cmp_std!(<> std::path::PathBuf, Path<Form>);
3075impl_cmp_std!(<'a> std::path::PathBuf, &'a Path<Form>);
3076impl_cmp_std!(<'a> Cow<'a, std::path::Path>, Path<Form>);
3077impl_cmp_std!(<'a, 'b> Cow<'a, std::path::Path>, &'b Path<Form>);
3078
3079impl_cmp_std!(<> std::path::Path, PathBuf<Form>);
3080impl_cmp_std!(<'a> &'a std::path::Path, PathBuf<Form>);
3081impl_cmp_std!(<> std::path::PathBuf, PathBuf<Form>);
3082impl_cmp_std!(<'a> Cow<'a, std::path::Path>, PathBuf<Form>);
3083
3084// === Between string types ===
3085
3086impl_cmp_std!(<> OsStr, Path<Form>);
3087impl_cmp_std!(<'a> OsStr, &'a Path<Form>);
3088impl_cmp_std!(<'a> &'a OsStr, Path<Form>);
3089impl_cmp_std!(<'a> Cow<'a, OsStr>, Path<Form>);
3090impl_cmp_std!(<'a, 'b> Cow<'b, OsStr>, &'a Path<Form>);
3091impl_cmp_std!(<> OsString, Path<Form>);
3092impl_cmp_std!(<'a> OsString, &'a Path<Form>);
3093
3094impl_cmp_std!(<> OsStr, PathBuf<Form>);
3095impl_cmp_std!(<'a> &'a OsStr, PathBuf<Form>);
3096impl_cmp_std!(<'a> Cow<'a, OsStr>, PathBuf<Form>);
3097impl_cmp_std!(<> OsString, PathBuf<Form>);