Thanks to visit codestin.com
Credit goes to doc.rust-lang.org

std/
path.rs

1//! Cross-platform path manipulation.
2//!
3//! This module provides two types, [`PathBuf`] and [`Path`] (akin to [`String`]
4//! and [`str`]), for working with paths abstractly. These types are thin wrappers
5//! around [`OsString`] and [`OsStr`] respectively, meaning that they work directly
6//! on strings according to the local platform's path syntax.
7//!
8//! Paths can be parsed into [`Component`]s by iterating over the structure
9//! returned by the [`components`] method on [`Path`]. [`Component`]s roughly
10//! correspond to the substrings between path separators (`/` or `\`). You can
11//! reconstruct an equivalent path from components with the [`push`] method on
12//! [`PathBuf`]; note that the paths may differ syntactically by the
13//! normalization described in the documentation for the [`components`] method.
14//!
15//! ## Case sensitivity
16//!
17//! Unless otherwise indicated path methods that do not access the filesystem,
18//! such as [`Path::starts_with`] and [`Path::ends_with`], are case sensitive no
19//! matter the platform or filesystem. An exception to this is made for Windows
20//! drive letters.
21//!
22//! ## Simple usage
23//!
24//! Path manipulation includes both parsing components from slices and building
25//! new owned paths.
26//!
27//! To parse a path, you can create a [`Path`] slice from a [`str`]
28//! slice and start asking questions:
29//!
30//! ```
31//! use std::path::Path;
32//! use std::ffi::OsStr;
33//!
34//! let path = Path::new("/tmp/foo/bar.txt");
35//!
36//! let parent = path.parent();
37//! assert_eq!(parent, Some(Path::new("/tmp/foo")));
38//!
39//! let file_stem = path.file_stem();
40//! assert_eq!(file_stem, Some(OsStr::new("bar")));
41//!
42//! let extension = path.extension();
43//! assert_eq!(extension, Some(OsStr::new("txt")));
44//! ```
45//!
46//! To build or modify paths, use [`PathBuf`]:
47//!
48//! ```
49//! use std::path::PathBuf;
50//!
51//! // This way works...
52//! let mut path = PathBuf::from("c:\\");
53//!
54//! path.push("windows");
55//! path.push("system32");
56//!
57//! path.set_extension("dll");
58//!
59//! // ... but push is best used if you don't know everything up
60//! // front. If you do, this way is better:
61//! let path: PathBuf = ["c:\\", "windows", "system32.dll"].iter().collect();
62//! ```
63//!
64//! [`components`]: Path::components
65//! [`push`]: PathBuf::push
66
67#![stable(feature = "rust1", since = "1.0.0")]
68#![deny(unsafe_op_in_unsafe_fn)]
69
70use core::clone::CloneToUninit;
71
72use crate::borrow::{Borrow, Cow};
73use crate::collections::TryReserveError;
74use crate::error::Error;
75use crate::ffi::{OsStr, OsString, os_str};
76use crate::hash::{Hash, Hasher};
77use crate::iter::FusedIterator;
78use crate::ops::{self, Deref};
79use crate::rc::Rc;
80use crate::str::FromStr;
81use crate::sync::Arc;
82use crate::sys::path::{HAS_PREFIXES, MAIN_SEP_STR, is_sep_byte, is_verbatim_sep, parse_prefix};
83use crate::{cmp, fmt, fs, io, sys};
84
85////////////////////////////////////////////////////////////////////////////////
86// GENERAL NOTES
87////////////////////////////////////////////////////////////////////////////////
88//
89// Parsing in this module is done by directly transmuting OsStr to [u8] slices,
90// taking advantage of the fact that OsStr always encodes ASCII characters
91// as-is.  Eventually, this transmutation should be replaced by direct uses of
92// OsStr APIs for parsing, but it will take a while for those to become
93// available.
94
95////////////////////////////////////////////////////////////////////////////////
96// Windows Prefixes
97////////////////////////////////////////////////////////////////////////////////
98
99/// Windows path prefixes, e.g., `C:` or `\\server\share`.
100///
101/// Windows uses a variety of path prefix styles, including references to drive
102/// volumes (like `C:`), network shared folders (like `\\server\share`), and
103/// others. In addition, some path prefixes are "verbatim" (i.e., prefixed with
104/// `\\?\`), in which case `/` is *not* treated as a separator and essentially
105/// no normalization is performed.
106///
107/// # Examples
108///
109/// ```
110/// use std::path::{Component, Path, Prefix};
111/// use std::path::Prefix::*;
112/// use std::ffi::OsStr;
113///
114/// fn get_path_prefix(s: &str) -> Prefix<'_> {
115///     let path = Path::new(s);
116///     match path.components().next().unwrap() {
117///         Component::Prefix(prefix_component) => prefix_component.kind(),
118///         _ => panic!(),
119///     }
120/// }
121///
122/// # if cfg!(windows) {
123/// assert_eq!(Verbatim(OsStr::new("pictures")),
124///            get_path_prefix(r"\\?\pictures\kittens"));
125/// assert_eq!(VerbatimUNC(OsStr::new("server"), OsStr::new("share")),
126///            get_path_prefix(r"\\?\UNC\server\share"));
127/// assert_eq!(VerbatimDisk(b'C'), get_path_prefix(r"\\?\c:\"));
128/// assert_eq!(DeviceNS(OsStr::new("BrainInterface")),
129///            get_path_prefix(r"\\.\BrainInterface"));
130/// assert_eq!(UNC(OsStr::new("server"), OsStr::new("share")),
131///            get_path_prefix(r"\\server\share"));
132/// assert_eq!(Disk(b'C'), get_path_prefix(r"C:\Users\Rust\Pictures\Ferris"));
133/// # }
134/// ```
135#[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
136#[stable(feature = "rust1", since = "1.0.0")]
137pub enum Prefix<'a> {
138    /// Verbatim prefix, e.g., `\\?\cat_pics`.
139    ///
140    /// Verbatim prefixes consist of `\\?\` immediately followed by the given
141    /// component.
142    #[stable(feature = "rust1", since = "1.0.0")]
143    Verbatim(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
144
145    /// Verbatim prefix using Windows' _**U**niform **N**aming **C**onvention_,
146    /// e.g., `\\?\UNC\server\share`.
147    ///
148    /// Verbatim UNC prefixes consist of `\\?\UNC\` immediately followed by the
149    /// server's hostname and a share name.
150    #[stable(feature = "rust1", since = "1.0.0")]
151    VerbatimUNC(
152        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
153        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
154    ),
155
156    /// Verbatim disk prefix, e.g., `\\?\C:`.
157    ///
158    /// Verbatim disk prefixes consist of `\\?\` immediately followed by the
159    /// drive letter and `:`.
160    #[stable(feature = "rust1", since = "1.0.0")]
161    VerbatimDisk(#[stable(feature = "rust1", since = "1.0.0")] u8),
162
163    /// Device namespace prefix, e.g., `\\.\COM42`.
164    ///
165    /// Device namespace prefixes consist of `\\.\` (possibly using `/`
166    /// instead of `\`), immediately followed by the device name.
167    #[stable(feature = "rust1", since = "1.0.0")]
168    DeviceNS(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
169
170    /// Prefix using Windows' _**U**niform **N**aming **C**onvention_, e.g.
171    /// `\\server\share`.
172    ///
173    /// UNC prefixes consist of the server's hostname and a share name.
174    #[stable(feature = "rust1", since = "1.0.0")]
175    UNC(
176        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
177        #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
178    ),
179
180    /// Prefix `C:` for the given disk drive.
181    #[stable(feature = "rust1", since = "1.0.0")]
182    Disk(#[stable(feature = "rust1", since = "1.0.0")] u8),
183}
184
185impl<'a> Prefix<'a> {
186    #[inline]
187    fn len(&self) -> usize {
188        use self::Prefix::*;
189        fn os_str_len(s: &OsStr) -> usize {
190            s.as_encoded_bytes().len()
191        }
192        match *self {
193            Verbatim(x) => 4 + os_str_len(x),
194            VerbatimUNC(x, y) => {
195                8 + os_str_len(x) + if os_str_len(y) > 0 { 1 + os_str_len(y) } else { 0 }
196            }
197            VerbatimDisk(_) => 6,
198            UNC(x, y) => 2 + os_str_len(x) + if os_str_len(y) > 0 { 1 + os_str_len(y) } else { 0 },
199            DeviceNS(x) => 4 + os_str_len(x),
200            Disk(_) => 2,
201        }
202    }
203
204    /// Determines if the prefix is verbatim, i.e., begins with `\\?\`.
205    ///
206    /// # Examples
207    ///
208    /// ```
209    /// use std::path::Prefix::*;
210    /// use std::ffi::OsStr;
211    ///
212    /// assert!(Verbatim(OsStr::new("pictures")).is_verbatim());
213    /// assert!(VerbatimUNC(OsStr::new("server"), OsStr::new("share")).is_verbatim());
214    /// assert!(VerbatimDisk(b'C').is_verbatim());
215    /// assert!(!DeviceNS(OsStr::new("BrainInterface")).is_verbatim());
216    /// assert!(!UNC(OsStr::new("server"), OsStr::new("share")).is_verbatim());
217    /// assert!(!Disk(b'C').is_verbatim());
218    /// ```
219    #[inline]
220    #[must_use]
221    #[stable(feature = "rust1", since = "1.0.0")]
222    pub fn is_verbatim(&self) -> bool {
223        use self::Prefix::*;
224        matches!(*self, Verbatim(_) | VerbatimDisk(_) | VerbatimUNC(..))
225    }
226
227    #[inline]
228    fn is_drive(&self) -> bool {
229        matches!(*self, Prefix::Disk(_))
230    }
231
232    #[inline]
233    fn has_implicit_root(&self) -> bool {
234        !self.is_drive()
235    }
236}
237
238////////////////////////////////////////////////////////////////////////////////
239// Exposed parsing helpers
240////////////////////////////////////////////////////////////////////////////////
241
242/// Determines whether the character is one of the permitted path
243/// separators for the current platform.
244///
245/// # Examples
246///
247/// ```
248/// use std::path;
249///
250/// assert!(path::is_separator('/')); // '/' works for both Unix and Windows
251/// assert!(!path::is_separator('❤'));
252/// ```
253#[must_use]
254#[stable(feature = "rust1", since = "1.0.0")]
255pub fn is_separator(c: char) -> bool {
256    c.is_ascii() && is_sep_byte(c as u8)
257}
258
259/// The primary separator of path components for the current platform.
260///
261/// For example, `/` on Unix and `\` on Windows.
262#[stable(feature = "rust1", since = "1.0.0")]
263#[cfg_attr(not(test), rustc_diagnostic_item = "path_main_separator")]
264pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP;
265
266/// The primary separator of path components for the current platform.
267///
268/// For example, `/` on Unix and `\` on Windows.
269#[stable(feature = "main_separator_str", since = "1.68.0")]
270pub const MAIN_SEPARATOR_STR: &str = crate::sys::path::MAIN_SEP_STR;
271
272////////////////////////////////////////////////////////////////////////////////
273// Misc helpers
274////////////////////////////////////////////////////////////////////////////////
275
276// Iterate through `iter` while it matches `prefix`; return `None` if `prefix`
277// is not a prefix of `iter`, otherwise return `Some(iter_after_prefix)` giving
278// `iter` after having exhausted `prefix`.
279fn iter_after<'a, 'b, I, J>(mut iter: I, mut prefix: J) -> Option<I>
280where
281    I: Iterator<Item = Component<'a>> + Clone,
282    J: Iterator<Item = Component<'b>>,
283{
284    loop {
285        let mut iter_next = iter.clone();
286        match (iter_next.next(), prefix.next()) {
287            (Some(ref x), Some(ref y)) if x == y => (),
288            (Some(_), Some(_)) => return None,
289            (Some(_), None) => return Some(iter),
290            (None, None) => return Some(iter),
291            (None, Some(_)) => return None,
292        }
293        iter = iter_next;
294    }
295}
296
297////////////////////////////////////////////////////////////////////////////////
298// Cross-platform, iterator-independent parsing
299////////////////////////////////////////////////////////////////////////////////
300
301/// Says whether the first byte after the prefix is a separator.
302fn has_physical_root(s: &[u8], prefix: Option<Prefix<'_>>) -> bool {
303    let path = if let Some(p) = prefix { &s[p.len()..] } else { s };
304    !path.is_empty() && is_sep_byte(path[0])
305}
306
307// basic workhorse for splitting stem and extension
308fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) {
309    if file.as_encoded_bytes() == b".." {
310        return (Some(file), None);
311    }
312
313    // The unsafety here stems from converting between &OsStr and &[u8]
314    // and back. This is safe to do because (1) we only look at ASCII
315    // contents of the encoding and (2) new &OsStr values are produced
316    // only from ASCII-bounded slices of existing &OsStr values.
317    let mut iter = file.as_encoded_bytes().rsplitn(2, |b| *b == b'.');
318    let after = iter.next();
319    let before = iter.next();
320    if before == Some(b"") {
321        (Some(file), None)
322    } else {
323        unsafe {
324            (
325                before.map(|s| OsStr::from_encoded_bytes_unchecked(s)),
326                after.map(|s| OsStr::from_encoded_bytes_unchecked(s)),
327            )
328        }
329    }
330}
331
332fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
333    let slice = file.as_encoded_bytes();
334    if slice == b".." {
335        return (file, None);
336    }
337
338    // The unsafety here stems from converting between &OsStr and &[u8]
339    // and back. This is safe to do because (1) we only look at ASCII
340    // contents of the encoding and (2) new &OsStr values are produced
341    // only from ASCII-bounded slices of existing &OsStr values.
342    let i = match slice[1..].iter().position(|b| *b == b'.') {
343        Some(i) => i + 1,
344        None => return (file, None),
345    };
346    let before = &slice[..i];
347    let after = &slice[i + 1..];
348    unsafe {
349        (
350            OsStr::from_encoded_bytes_unchecked(before),
351            Some(OsStr::from_encoded_bytes_unchecked(after)),
352        )
353    }
354}
355
356/// Checks whether the string is valid as a file extension, or panics otherwise.
357fn validate_extension(extension: &OsStr) {
358    for &b in extension.as_encoded_bytes() {
359        if is_sep_byte(b) {
360            panic!("extension cannot contain path separators: {extension:?}");
361        }
362    }
363}
364
365////////////////////////////////////////////////////////////////////////////////
366// The core iterators
367////////////////////////////////////////////////////////////////////////////////
368
369/// Component parsing works by a double-ended state machine; the cursors at the
370/// front and back of the path each keep track of what parts of the path have
371/// been consumed so far.
372///
373/// Going front to back, a path is made up of a prefix, a starting
374/// directory component, and a body (of normal components)
375#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
376enum State {
377    Prefix = 0,   // c:
378    StartDir = 1, // / or . or nothing
379    Body = 2,     // foo/bar/baz
380    Done = 3,
381}
382
383/// A structure wrapping a Windows path prefix as well as its unparsed string
384/// representation.
385///
386/// In addition to the parsed [`Prefix`] information returned by [`kind`],
387/// `PrefixComponent` also holds the raw and unparsed [`OsStr`] slice,
388/// returned by [`as_os_str`].
389///
390/// Instances of this `struct` can be obtained by matching against the
391/// [`Prefix` variant] on [`Component`].
392///
393/// Does not occur on Unix.
394///
395/// # Examples
396///
397/// ```
398/// # if cfg!(windows) {
399/// use std::path::{Component, Path, Prefix};
400/// use std::ffi::OsStr;
401///
402/// let path = Path::new(r"c:\you\later\");
403/// match path.components().next().unwrap() {
404///     Component::Prefix(prefix_component) => {
405///         assert_eq!(Prefix::Disk(b'C'), prefix_component.kind());
406///         assert_eq!(OsStr::new("c:"), prefix_component.as_os_str());
407///     }
408///     _ => unreachable!(),
409/// }
410/// # }
411/// ```
412///
413/// [`as_os_str`]: PrefixComponent::as_os_str
414/// [`kind`]: PrefixComponent::kind
415/// [`Prefix` variant]: Component::Prefix
416#[stable(feature = "rust1", since = "1.0.0")]
417#[derive(Copy, Clone, Eq, Debug)]
418pub struct PrefixComponent<'a> {
419    /// The prefix as an unparsed `OsStr` slice.
420    raw: &'a OsStr,
421
422    /// The parsed prefix data.
423    parsed: Prefix<'a>,
424}
425
426impl<'a> PrefixComponent<'a> {
427    /// Returns the parsed prefix data.
428    ///
429    /// See [`Prefix`]'s documentation for more information on the different
430    /// kinds of prefixes.
431    #[stable(feature = "rust1", since = "1.0.0")]
432    #[must_use]
433    #[inline]
434    pub fn kind(&self) -> Prefix<'a> {
435        self.parsed
436    }
437
438    /// Returns the raw [`OsStr`] slice for this prefix.
439    #[stable(feature = "rust1", since = "1.0.0")]
440    #[must_use]
441    #[inline]
442    pub fn as_os_str(&self) -> &'a OsStr {
443        self.raw
444    }
445}
446
447#[stable(feature = "rust1", since = "1.0.0")]
448impl<'a> PartialEq for PrefixComponent<'a> {
449    #[inline]
450    fn eq(&self, other: &PrefixComponent<'a>) -> bool {
451        self.parsed == other.parsed
452    }
453}
454
455#[stable(feature = "rust1", since = "1.0.0")]
456impl<'a> PartialOrd for PrefixComponent<'a> {
457    #[inline]
458    fn partial_cmp(&self, other: &PrefixComponent<'a>) -> Option<cmp::Ordering> {
459        PartialOrd::partial_cmp(&self.parsed, &other.parsed)
460    }
461}
462
463#[stable(feature = "rust1", since = "1.0.0")]
464impl Ord for PrefixComponent<'_> {
465    #[inline]
466    fn cmp(&self, other: &Self) -> cmp::Ordering {
467        Ord::cmp(&self.parsed, &other.parsed)
468    }
469}
470
471#[stable(feature = "rust1", since = "1.0.0")]
472impl Hash for PrefixComponent<'_> {
473    fn hash<H: Hasher>(&self, h: &mut H) {
474        self.parsed.hash(h);
475    }
476}
477
478/// A single component of a path.
479///
480/// A `Component` roughly corresponds to a substring between path separators
481/// (`/` or `\`).
482///
483/// This `enum` is created by iterating over [`Components`], which in turn is
484/// created by the [`components`](Path::components) method on [`Path`].
485///
486/// # Examples
487///
488/// ```rust
489/// use std::path::{Component, Path};
490///
491/// let path = Path::new("/tmp/foo/bar.txt");
492/// let components = path.components().collect::<Vec<_>>();
493/// assert_eq!(&components, &[
494///     Component::RootDir,
495///     Component::Normal("tmp".as_ref()),
496///     Component::Normal("foo".as_ref()),
497///     Component::Normal("bar.txt".as_ref()),
498/// ]);
499/// ```
500#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
501#[stable(feature = "rust1", since = "1.0.0")]
502pub enum Component<'a> {
503    /// A Windows path prefix, e.g., `C:` or `\\server\share`.
504    ///
505    /// There is a large variety of prefix types, see [`Prefix`]'s documentation
506    /// for more.
507    ///
508    /// Does not occur on Unix.
509    #[stable(feature = "rust1", since = "1.0.0")]
510    Prefix(#[stable(feature = "rust1", since = "1.0.0")] PrefixComponent<'a>),
511
512    /// The root directory component, appears after any prefix and before anything else.
513    ///
514    /// It represents a separator that designates that a path starts from root.
515    #[stable(feature = "rust1", since = "1.0.0")]
516    RootDir,
517
518    /// A reference to the current directory, i.e., `.`.
519    #[stable(feature = "rust1", since = "1.0.0")]
520    CurDir,
521
522    /// A reference to the parent directory, i.e., `..`.
523    #[stable(feature = "rust1", since = "1.0.0")]
524    ParentDir,
525
526    /// A normal component, e.g., `a` and `b` in `a/b`.
527    ///
528    /// This variant is the most common one, it represents references to files
529    /// or directories.
530    #[stable(feature = "rust1", since = "1.0.0")]
531    Normal(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
532}
533
534impl<'a> Component<'a> {
535    /// Extracts the underlying [`OsStr`] slice.
536    ///
537    /// # Examples
538    ///
539    /// ```
540    /// use std::path::Path;
541    ///
542    /// let path = Path::new("./tmp/foo/bar.txt");
543    /// let components: Vec<_> = path.components().map(|comp| comp.as_os_str()).collect();
544    /// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
545    /// ```
546    #[must_use = "`self` will be dropped if the result is not used"]
547    #[stable(feature = "rust1", since = "1.0.0")]
548    pub fn as_os_str(self) -> &'a OsStr {
549        match self {
550            Component::Prefix(p) => p.as_os_str(),
551            Component::RootDir => OsStr::new(MAIN_SEP_STR),
552            Component::CurDir => OsStr::new("."),
553            Component::ParentDir => OsStr::new(".."),
554            Component::Normal(path) => path,
555        }
556    }
557}
558
559#[stable(feature = "rust1", since = "1.0.0")]
560impl AsRef<OsStr> for Component<'_> {
561    #[inline]
562    fn as_ref(&self) -> &OsStr {
563        self.as_os_str()
564    }
565}
566
567#[stable(feature = "path_component_asref", since = "1.25.0")]
568impl AsRef<Path> for Component<'_> {
569    #[inline]
570    fn as_ref(&self) -> &Path {
571        self.as_os_str().as_ref()
572    }
573}
574
575/// An iterator over the [`Component`]s of a [`Path`].
576///
577/// This `struct` is created by the [`components`] method on [`Path`].
578/// See its documentation for more.
579///
580/// # Examples
581///
582/// ```
583/// use std::path::Path;
584///
585/// let path = Path::new("/tmp/foo/bar.txt");
586///
587/// for component in path.components() {
588///     println!("{component:?}");
589/// }
590/// ```
591///
592/// [`components`]: Path::components
593#[derive(Clone)]
594#[must_use = "iterators are lazy and do nothing unless consumed"]
595#[stable(feature = "rust1", since = "1.0.0")]
596pub struct Components<'a> {
597    // The path left to parse components from
598    path: &'a [u8],
599
600    // The prefix as it was originally parsed, if any
601    prefix: Option<Prefix<'a>>,
602
603    // true if path *physically* has a root separator; for most Windows
604    // prefixes, it may have a "logical" root separator for the purposes of
605    // normalization, e.g., \\server\share == \\server\share\.
606    has_physical_root: bool,
607
608    // The iterator is double-ended, and these two states keep track of what has
609    // been produced from either end
610    front: State,
611    back: State,
612}
613
614/// An iterator over the [`Component`]s of a [`Path`], as [`OsStr`] slices.
615///
616/// This `struct` is created by the [`iter`] method on [`Path`].
617/// See its documentation for more.
618///
619/// [`iter`]: Path::iter
620#[derive(Clone)]
621#[must_use = "iterators are lazy and do nothing unless consumed"]
622#[stable(feature = "rust1", since = "1.0.0")]
623pub struct Iter<'a> {
624    inner: Components<'a>,
625}
626
627#[stable(feature = "path_components_debug", since = "1.13.0")]
628impl fmt::Debug for Components<'_> {
629    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
630        struct DebugHelper<'a>(&'a Path);
631
632        impl fmt::Debug for DebugHelper<'_> {
633            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
634                f.debug_list().entries(self.0.components()).finish()
635            }
636        }
637
638        f.debug_tuple("Components").field(&DebugHelper(self.as_path())).finish()
639    }
640}
641
642impl<'a> Components<'a> {
643    // how long is the prefix, if any?
644    #[inline]
645    fn prefix_len(&self) -> usize {
646        if !HAS_PREFIXES {
647            return 0;
648        }
649        self.prefix.as_ref().map(Prefix::len).unwrap_or(0)
650    }
651
652    #[inline]
653    fn prefix_verbatim(&self) -> bool {
654        if !HAS_PREFIXES {
655            return false;
656        }
657        self.prefix.as_ref().map(Prefix::is_verbatim).unwrap_or(false)
658    }
659
660    /// how much of the prefix is left from the point of view of iteration?
661    #[inline]
662    fn prefix_remaining(&self) -> usize {
663        if !HAS_PREFIXES {
664            return 0;
665        }
666        if self.front == State::Prefix { self.prefix_len() } else { 0 }
667    }
668
669    // Given the iteration so far, how much of the pre-State::Body path is left?
670    #[inline]
671    fn len_before_body(&self) -> usize {
672        let root = if self.front <= State::StartDir && self.has_physical_root { 1 } else { 0 };
673        let cur_dir = if self.front <= State::StartDir && self.include_cur_dir() { 1 } else { 0 };
674        self.prefix_remaining() + root + cur_dir
675    }
676
677    // is the iteration complete?
678    #[inline]
679    fn finished(&self) -> bool {
680        self.front == State::Done || self.back == State::Done || self.front > self.back
681    }
682
683    #[inline]
684    fn is_sep_byte(&self, b: u8) -> bool {
685        if self.prefix_verbatim() { is_verbatim_sep(b) } else { is_sep_byte(b) }
686    }
687
688    /// Extracts a slice corresponding to the portion of the path remaining for iteration.
689    ///
690    /// # Examples
691    ///
692    /// ```
693    /// use std::path::Path;
694    ///
695    /// let mut components = Path::new("/tmp/foo/bar.txt").components();
696    /// components.next();
697    /// components.next();
698    ///
699    /// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
700    /// ```
701    #[must_use]
702    #[stable(feature = "rust1", since = "1.0.0")]
703    pub fn as_path(&self) -> &'a Path {
704        let mut comps = self.clone();
705        if comps.front == State::Body {
706            comps.trim_left();
707        }
708        if comps.back == State::Body {
709            comps.trim_right();
710        }
711        unsafe { Path::from_u8_slice(comps.path) }
712    }
713
714    /// Is the *original* path rooted?
715    fn has_root(&self) -> bool {
716        if self.has_physical_root {
717            return true;
718        }
719        if HAS_PREFIXES && let Some(p) = self.prefix {
720            if p.has_implicit_root() {
721                return true;
722            }
723        }
724        false
725    }
726
727    /// Should the normalized path include a leading . ?
728    fn include_cur_dir(&self) -> bool {
729        if self.has_root() {
730            return false;
731        }
732        let slice = &self.path[self.prefix_remaining()..];
733        match slice {
734            [b'.'] => true,
735            [b'.', b, ..] => self.is_sep_byte(*b),
736            _ => false,
737        }
738    }
739
740    // parse a given byte sequence following the OsStr encoding into the
741    // corresponding path component
742    unsafe fn parse_single_component<'b>(&self, comp: &'b [u8]) -> Option<Component<'b>> {
743        match comp {
744            b"." if HAS_PREFIXES && self.prefix_verbatim() => Some(Component::CurDir),
745            b"." => None, // . components are normalized away, except at
746            // the beginning of a path, which is treated
747            // separately via `include_cur_dir`
748            b".." => Some(Component::ParentDir),
749            b"" => None,
750            _ => Some(Component::Normal(unsafe { OsStr::from_encoded_bytes_unchecked(comp) })),
751        }
752    }
753
754    // parse a component from the left, saying how many bytes to consume to
755    // remove the component
756    fn parse_next_component(&self) -> (usize, Option<Component<'a>>) {
757        debug_assert!(self.front == State::Body);
758        let (extra, comp) = match self.path.iter().position(|b| self.is_sep_byte(*b)) {
759            None => (0, self.path),
760            Some(i) => (1, &self.path[..i]),
761        };
762        // SAFETY: `comp` is a valid substring, since it is split on a separator.
763        (comp.len() + extra, unsafe { self.parse_single_component(comp) })
764    }
765
766    // parse a component from the right, saying how many bytes to consume to
767    // remove the component
768    fn parse_next_component_back(&self) -> (usize, Option<Component<'a>>) {
769        debug_assert!(self.back == State::Body);
770        let start = self.len_before_body();
771        let (extra, comp) = match self.path[start..].iter().rposition(|b| self.is_sep_byte(*b)) {
772            None => (0, &self.path[start..]),
773            Some(i) => (1, &self.path[start + i + 1..]),
774        };
775        // SAFETY: `comp` is a valid substring, since it is split on a separator.
776        (comp.len() + extra, unsafe { self.parse_single_component(comp) })
777    }
778
779    // trim away repeated separators (i.e., empty components) on the left
780    fn trim_left(&mut self) {
781        while !self.path.is_empty() {
782            let (size, comp) = self.parse_next_component();
783            if comp.is_some() {
784                return;
785            } else {
786                self.path = &self.path[size..];
787            }
788        }
789    }
790
791    // trim away repeated separators (i.e., empty components) on the right
792    fn trim_right(&mut self) {
793        while self.path.len() > self.len_before_body() {
794            let (size, comp) = self.parse_next_component_back();
795            if comp.is_some() {
796                return;
797            } else {
798                self.path = &self.path[..self.path.len() - size];
799            }
800        }
801    }
802}
803
804#[stable(feature = "rust1", since = "1.0.0")]
805impl AsRef<Path> for Components<'_> {
806    #[inline]
807    fn as_ref(&self) -> &Path {
808        self.as_path()
809    }
810}
811
812#[stable(feature = "rust1", since = "1.0.0")]
813impl AsRef<OsStr> for Components<'_> {
814    #[inline]
815    fn as_ref(&self) -> &OsStr {
816        self.as_path().as_os_str()
817    }
818}
819
820#[stable(feature = "path_iter_debug", since = "1.13.0")]
821impl fmt::Debug for Iter<'_> {
822    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
823        struct DebugHelper<'a>(&'a Path);
824
825        impl fmt::Debug for DebugHelper<'_> {
826            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
827                f.debug_list().entries(self.0.iter()).finish()
828            }
829        }
830
831        f.debug_tuple("Iter").field(&DebugHelper(self.as_path())).finish()
832    }
833}
834
835impl<'a> Iter<'a> {
836    /// Extracts a slice corresponding to the portion of the path remaining for iteration.
837    ///
838    /// # Examples
839    ///
840    /// ```
841    /// use std::path::Path;
842    ///
843    /// let mut iter = Path::new("/tmp/foo/bar.txt").iter();
844    /// iter.next();
845    /// iter.next();
846    ///
847    /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
848    /// ```
849    #[stable(feature = "rust1", since = "1.0.0")]
850    #[must_use]
851    #[inline]
852    pub fn as_path(&self) -> &'a Path {
853        self.inner.as_path()
854    }
855}
856
857#[stable(feature = "rust1", since = "1.0.0")]
858impl AsRef<Path> for Iter<'_> {
859    #[inline]
860    fn as_ref(&self) -> &Path {
861        self.as_path()
862    }
863}
864
865#[stable(feature = "rust1", since = "1.0.0")]
866impl AsRef<OsStr> for Iter<'_> {
867    #[inline]
868    fn as_ref(&self) -> &OsStr {
869        self.as_path().as_os_str()
870    }
871}
872
873#[stable(feature = "rust1", since = "1.0.0")]
874impl<'a> Iterator for Iter<'a> {
875    type Item = &'a OsStr;
876
877    #[inline]
878    fn next(&mut self) -> Option<&'a OsStr> {
879        self.inner.next().map(Component::as_os_str)
880    }
881}
882
883#[stable(feature = "rust1", since = "1.0.0")]
884impl<'a> DoubleEndedIterator for Iter<'a> {
885    #[inline]
886    fn next_back(&mut self) -> Option<&'a OsStr> {
887        self.inner.next_back().map(Component::as_os_str)
888    }
889}
890
891#[stable(feature = "fused", since = "1.26.0")]
892impl FusedIterator for Iter<'_> {}
893
894#[stable(feature = "rust1", since = "1.0.0")]
895impl<'a> Iterator for Components<'a> {
896    type Item = Component<'a>;
897
898    fn next(&mut self) -> Option<Component<'a>> {
899        while !self.finished() {
900            match self.front {
901                // most likely case first
902                State::Body if !self.path.is_empty() => {
903                    let (size, comp) = self.parse_next_component();
904                    self.path = &self.path[size..];
905                    if comp.is_some() {
906                        return comp;
907                    }
908                }
909                State::Body => {
910                    self.front = State::Done;
911                }
912                State::StartDir => {
913                    self.front = State::Body;
914                    if self.has_physical_root {
915                        debug_assert!(!self.path.is_empty());
916                        self.path = &self.path[1..];
917                        return Some(Component::RootDir);
918                    } else if HAS_PREFIXES && let Some(p) = self.prefix {
919                        if p.has_implicit_root() && !p.is_verbatim() {
920                            return Some(Component::RootDir);
921                        }
922                    } else if self.include_cur_dir() {
923                        debug_assert!(!self.path.is_empty());
924                        self.path = &self.path[1..];
925                        return Some(Component::CurDir);
926                    }
927                }
928                _ if const { !HAS_PREFIXES } => unreachable!(),
929                State::Prefix if self.prefix_len() == 0 => {
930                    self.front = State::StartDir;
931                }
932                State::Prefix => {
933                    self.front = State::StartDir;
934                    debug_assert!(self.prefix_len() <= self.path.len());
935                    let raw = &self.path[..self.prefix_len()];
936                    self.path = &self.path[self.prefix_len()..];
937                    return Some(Component::Prefix(PrefixComponent {
938                        raw: unsafe { OsStr::from_encoded_bytes_unchecked(raw) },
939                        parsed: self.prefix.unwrap(),
940                    }));
941                }
942                State::Done => unreachable!(),
943            }
944        }
945        None
946    }
947}
948
949#[stable(feature = "rust1", since = "1.0.0")]
950impl<'a> DoubleEndedIterator for Components<'a> {
951    fn next_back(&mut self) -> Option<Component<'a>> {
952        while !self.finished() {
953            match self.back {
954                State::Body if self.path.len() > self.len_before_body() => {
955                    let (size, comp) = self.parse_next_component_back();
956                    self.path = &self.path[..self.path.len() - size];
957                    if comp.is_some() {
958                        return comp;
959                    }
960                }
961                State::Body => {
962                    self.back = State::StartDir;
963                }
964                State::StartDir => {
965                    self.back = if HAS_PREFIXES { State::Prefix } else { State::Done };
966                    if self.has_physical_root {
967                        self.path = &self.path[..self.path.len() - 1];
968                        return Some(Component::RootDir);
969                    } else if HAS_PREFIXES && let Some(p) = self.prefix {
970                        if p.has_implicit_root() && !p.is_verbatim() {
971                            return Some(Component::RootDir);
972                        }
973                    } else if self.include_cur_dir() {
974                        self.path = &self.path[..self.path.len() - 1];
975                        return Some(Component::CurDir);
976                    }
977                }
978                _ if !HAS_PREFIXES => unreachable!(),
979                State::Prefix if self.prefix_len() > 0 => {
980                    self.back = State::Done;
981                    return Some(Component::Prefix(PrefixComponent {
982                        raw: unsafe { OsStr::from_encoded_bytes_unchecked(self.path) },
983                        parsed: self.prefix.unwrap(),
984                    }));
985                }
986                State::Prefix => {
987                    self.back = State::Done;
988                    return None;
989                }
990                State::Done => unreachable!(),
991            }
992        }
993        None
994    }
995}
996
997#[stable(feature = "fused", since = "1.26.0")]
998impl FusedIterator for Components<'_> {}
999
1000#[stable(feature = "rust1", since = "1.0.0")]
1001impl<'a> PartialEq for Components<'a> {
1002    #[inline]
1003    fn eq(&self, other: &Components<'a>) -> bool {
1004        let Components { path: _, front: _, back: _, has_physical_root: _, prefix: _ } = self;
1005
1006        // Fast path for exact matches, e.g. for hashmap lookups.
1007        // Don't explicitly compare the prefix or has_physical_root fields since they'll
1008        // either be covered by the `path` buffer or are only relevant for `prefix_verbatim()`.
1009        if self.path.len() == other.path.len()
1010            && self.front == other.front
1011            && self.back == State::Body
1012            && other.back == State::Body
1013            && self.prefix_verbatim() == other.prefix_verbatim()
1014        {
1015            // possible future improvement: this could bail out earlier if there were a
1016            // reverse memcmp/bcmp comparing back to front
1017            if self.path == other.path {
1018                return true;
1019            }
1020        }
1021
1022        // compare back to front since absolute paths often share long prefixes
1023        Iterator::eq(self.clone().rev(), other.clone().rev())
1024    }
1025}
1026
1027#[stable(feature = "rust1", since = "1.0.0")]
1028impl Eq for Components<'_> {}
1029
1030#[stable(feature = "rust1", since = "1.0.0")]
1031impl<'a> PartialOrd for Components<'a> {
1032    #[inline]
1033    fn partial_cmp(&self, other: &Components<'a>) -> Option<cmp::Ordering> {
1034        Some(compare_components(self.clone(), other.clone()))
1035    }
1036}
1037
1038#[stable(feature = "rust1", since = "1.0.0")]
1039impl Ord for Components<'_> {
1040    #[inline]
1041    fn cmp(&self, other: &Self) -> cmp::Ordering {
1042        compare_components(self.clone(), other.clone())
1043    }
1044}
1045
1046fn compare_components(mut left: Components<'_>, mut right: Components<'_>) -> cmp::Ordering {
1047    // Fast path for long shared prefixes
1048    //
1049    // - compare raw bytes to find first mismatch
1050    // - backtrack to find separator before mismatch to avoid ambiguous parsings of '.' or '..' characters
1051    // - if found update state to only do a component-wise comparison on the remainder,
1052    //   otherwise do it on the full path
1053    //
1054    // The fast path isn't taken for paths with a PrefixComponent to avoid backtracking into
1055    // the middle of one
1056    if left.prefix.is_none() && right.prefix.is_none() && left.front == right.front {
1057        // possible future improvement: a [u8]::first_mismatch simd implementation
1058        let first_difference = match left.path.iter().zip(right.path).position(|(&a, &b)| a != b) {
1059            None if left.path.len() == right.path.len() => return cmp::Ordering::Equal,
1060            None => left.path.len().min(right.path.len()),
1061            Some(diff) => diff,
1062        };
1063
1064        if let Some(previous_sep) =
1065            left.path[..first_difference].iter().rposition(|&b| left.is_sep_byte(b))
1066        {
1067            let mismatched_component_start = previous_sep + 1;
1068            left.path = &left.path[mismatched_component_start..];
1069            left.front = State::Body;
1070            right.path = &right.path[mismatched_component_start..];
1071            right.front = State::Body;
1072        }
1073    }
1074
1075    Iterator::cmp(left, right)
1076}
1077
1078/// An iterator over [`Path`] and its ancestors.
1079///
1080/// This `struct` is created by the [`ancestors`] method on [`Path`].
1081/// See its documentation for more.
1082///
1083/// # Examples
1084///
1085/// ```
1086/// use std::path::Path;
1087///
1088/// let path = Path::new("/foo/bar");
1089///
1090/// for ancestor in path.ancestors() {
1091///     println!("{}", ancestor.display());
1092/// }
1093/// ```
1094///
1095/// [`ancestors`]: Path::ancestors
1096#[derive(Copy, Clone, Debug)]
1097#[must_use = "iterators are lazy and do nothing unless consumed"]
1098#[stable(feature = "path_ancestors", since = "1.28.0")]
1099pub struct Ancestors<'a> {
1100    next: Option<&'a Path>,
1101}
1102
1103#[stable(feature = "path_ancestors", since = "1.28.0")]
1104impl<'a> Iterator for Ancestors<'a> {
1105    type Item = &'a Path;
1106
1107    #[inline]
1108    fn next(&mut self) -> Option<Self::Item> {
1109        let next = self.next;
1110        self.next = next.and_then(Path::parent);
1111        next
1112    }
1113}
1114
1115#[stable(feature = "path_ancestors", since = "1.28.0")]
1116impl FusedIterator for Ancestors<'_> {}
1117
1118////////////////////////////////////////////////////////////////////////////////
1119// Basic types and traits
1120////////////////////////////////////////////////////////////////////////////////
1121
1122/// An owned, mutable path (akin to [`String`]).
1123///
1124/// This type provides methods like [`push`] and [`set_extension`] that mutate
1125/// the path in place. It also implements [`Deref`] to [`Path`], meaning that
1126/// all methods on [`Path`] slices are available on `PathBuf` values as well.
1127///
1128/// [`push`]: PathBuf::push
1129/// [`set_extension`]: PathBuf::set_extension
1130///
1131/// More details about the overall approach can be found in
1132/// the [module documentation](self).
1133///
1134/// # Examples
1135///
1136/// You can use [`push`] to build up a `PathBuf` from
1137/// components:
1138///
1139/// ```
1140/// use std::path::PathBuf;
1141///
1142/// let mut path = PathBuf::new();
1143///
1144/// path.push(r"C:\");
1145/// path.push("windows");
1146/// path.push("system32");
1147///
1148/// path.set_extension("dll");
1149/// ```
1150///
1151/// However, [`push`] is best used for dynamic situations. This is a better way
1152/// to do this when you know all of the components ahead of time:
1153///
1154/// ```
1155/// use std::path::PathBuf;
1156///
1157/// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
1158/// ```
1159///
1160/// We can still do better than this! Since these are all strings, we can use
1161/// `From::from`:
1162///
1163/// ```
1164/// use std::path::PathBuf;
1165///
1166/// let path = PathBuf::from(r"C:\windows\system32.dll");
1167/// ```
1168///
1169/// Which method works best depends on what kind of situation you're in.
1170///
1171/// Note that `PathBuf` does not always sanitize arguments, for example
1172/// [`push`] allows paths built from strings which include separators:
1173///
1174/// ```
1175/// use std::path::PathBuf;
1176///
1177/// let mut path = PathBuf::new();
1178///
1179/// path.push(r"C:\");
1180/// path.push("windows");
1181/// path.push(r"..\otherdir");
1182/// path.push("system32");
1183/// ```
1184///
1185/// The behavior of `PathBuf` may be changed to a panic on such inputs
1186/// in the future. [`Extend::extend`] should be used to add multi-part paths.
1187#[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
1188#[stable(feature = "rust1", since = "1.0.0")]
1189pub struct PathBuf {
1190    inner: OsString,
1191}
1192
1193impl PathBuf {
1194    /// Allocates an empty `PathBuf`.
1195    ///
1196    /// # Examples
1197    ///
1198    /// ```
1199    /// use std::path::PathBuf;
1200    ///
1201    /// let path = PathBuf::new();
1202    /// ```
1203    #[stable(feature = "rust1", since = "1.0.0")]
1204    #[must_use]
1205    #[inline]
1206    #[rustc_const_stable(feature = "const_pathbuf_osstring_new", since = "1.91.0")]
1207    pub const fn new() -> PathBuf {
1208        PathBuf { inner: OsString::new() }
1209    }
1210
1211    /// Creates a new `PathBuf` with a given capacity used to create the
1212    /// internal [`OsString`]. See [`with_capacity`] defined on [`OsString`].
1213    ///
1214    /// # Examples
1215    ///
1216    /// ```
1217    /// use std::path::PathBuf;
1218    ///
1219    /// let mut path = PathBuf::with_capacity(10);
1220    /// let capacity = path.capacity();
1221    ///
1222    /// // This push is done without reallocating
1223    /// path.push(r"C:\");
1224    ///
1225    /// assert_eq!(capacity, path.capacity());
1226    /// ```
1227    ///
1228    /// [`with_capacity`]: OsString::with_capacity
1229    #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1230    #[must_use]
1231    #[inline]
1232    pub fn with_capacity(capacity: usize) -> PathBuf {
1233        PathBuf { inner: OsString::with_capacity(capacity) }
1234    }
1235
1236    /// Coerces to a [`Path`] slice.
1237    ///
1238    /// # Examples
1239    ///
1240    /// ```
1241    /// use std::path::{Path, PathBuf};
1242    ///
1243    /// let p = PathBuf::from("/test");
1244    /// assert_eq!(Path::new("/test"), p.as_path());
1245    /// ```
1246    #[cfg_attr(not(test), rustc_diagnostic_item = "pathbuf_as_path")]
1247    #[stable(feature = "rust1", since = "1.0.0")]
1248    #[must_use]
1249    #[inline]
1250    pub fn as_path(&self) -> &Path {
1251        self
1252    }
1253
1254    /// Consumes and leaks the `PathBuf`, returning a mutable reference to the contents,
1255    /// `&'a mut Path`.
1256    ///
1257    /// The caller has free choice over the returned lifetime, including 'static.
1258    /// Indeed, this function is ideally used for data that lives for the remainder of
1259    /// the program's life, as dropping the returned reference will cause a memory leak.
1260    ///
1261    /// It does not reallocate or shrink the `PathBuf`, so the leaked allocation may include
1262    /// unused capacity that is not part of the returned slice. If you want to discard excess
1263    /// capacity, call [`into_boxed_path`], and then [`Box::leak`] instead.
1264    /// However, keep in mind that trimming the capacity may result in a reallocation and copy.
1265    ///
1266    /// [`into_boxed_path`]: Self::into_boxed_path
1267    #[stable(feature = "os_string_pathbuf_leak", since = "1.89.0")]
1268    #[inline]
1269    pub fn leak<'a>(self) -> &'a mut Path {
1270        Path::from_inner_mut(self.inner.leak())
1271    }
1272
1273    /// Extends `self` with `path`.
1274    ///
1275    /// If `path` is absolute, it replaces the current path.
1276    ///
1277    /// On Windows:
1278    ///
1279    /// * if `path` has a root but no prefix (e.g., `\windows`), it
1280    ///   replaces everything except for the prefix (if any) of `self`.
1281    /// * if `path` has a prefix but no root, it replaces `self`.
1282    /// * if `self` has a verbatim prefix (e.g. `\\?\C:\windows`)
1283    ///   and `path` is not empty, the new path is normalized: all references
1284    ///   to `.` and `..` are removed.
1285    ///
1286    /// Consider using [`Path::join`] if you need a new `PathBuf` instead of
1287    /// using this function on a cloned `PathBuf`.
1288    ///
1289    /// # Examples
1290    ///
1291    /// Pushing a relative path extends the existing path:
1292    ///
1293    /// ```
1294    /// use std::path::PathBuf;
1295    ///
1296    /// let mut path = PathBuf::from("/tmp");
1297    /// path.push("file.bk");
1298    /// assert_eq!(path, PathBuf::from("/tmp/file.bk"));
1299    /// ```
1300    ///
1301    /// Pushing an absolute path replaces the existing path:
1302    ///
1303    /// ```
1304    /// use std::path::PathBuf;
1305    ///
1306    /// let mut path = PathBuf::from("/tmp");
1307    /// path.push("/etc");
1308    /// assert_eq!(path, PathBuf::from("/etc"));
1309    /// ```
1310    #[stable(feature = "rust1", since = "1.0.0")]
1311    #[rustc_confusables("append", "put")]
1312    pub fn push<P: AsRef<Path>>(&mut self, path: P) {
1313        self._push(path.as_ref())
1314    }
1315
1316    fn _push(&mut self, path: &Path) {
1317        // in general, a separator is needed if the rightmost byte is not a separator
1318        let buf = self.inner.as_encoded_bytes();
1319        let mut need_sep = buf.last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
1320
1321        // in the special case of `C:` on Windows, do *not* add a separator
1322        let comps = self.components();
1323
1324        if comps.prefix_len() > 0
1325            && comps.prefix_len() == comps.path.len()
1326            && comps.prefix.unwrap().is_drive()
1327        {
1328            need_sep = false
1329        }
1330
1331        let need_clear = if cfg!(target_os = "cygwin") {
1332            // If path is absolute and its prefix is none, it is like `/foo`,
1333            // and will be handled below.
1334            path.prefix().is_some()
1335        } else {
1336            // On Unix: prefix is always None.
1337            path.is_absolute() || path.prefix().is_some()
1338        };
1339
1340        // absolute `path` replaces `self`
1341        if need_clear {
1342            self.inner.truncate(0);
1343
1344        // verbatim paths need . and .. removed
1345        } else if comps.prefix_verbatim() && !path.inner.is_empty() {
1346            let mut buf: Vec<_> = comps.collect();
1347            for c in path.components() {
1348                match c {
1349                    Component::RootDir => {
1350                        buf.truncate(1);
1351                        buf.push(c);
1352                    }
1353                    Component::CurDir => (),
1354                    Component::ParentDir => {
1355                        if let Some(Component::Normal(_)) = buf.last() {
1356                            buf.pop();
1357                        }
1358                    }
1359                    _ => buf.push(c),
1360                }
1361            }
1362
1363            let mut res = OsString::new();
1364            let mut need_sep = false;
1365
1366            for c in buf {
1367                if need_sep && c != Component::RootDir {
1368                    res.push(MAIN_SEP_STR);
1369                }
1370                res.push(c.as_os_str());
1371
1372                need_sep = match c {
1373                    Component::RootDir => false,
1374                    Component::Prefix(prefix) => {
1375                        !prefix.parsed.is_drive() && prefix.parsed.len() > 0
1376                    }
1377                    _ => true,
1378                }
1379            }
1380
1381            self.inner = res;
1382            return;
1383
1384        // `path` has a root but no prefix, e.g., `\windows` (Windows only)
1385        } else if path.has_root() {
1386            let prefix_len = self.components().prefix_remaining();
1387            self.inner.truncate(prefix_len);
1388
1389        // `path` is a pure relative path
1390        } else if need_sep {
1391            self.inner.push(MAIN_SEP_STR);
1392        }
1393
1394        self.inner.push(path);
1395    }
1396
1397    /// Truncates `self` to [`self.parent`].
1398    ///
1399    /// Returns `false` and does nothing if [`self.parent`] is [`None`].
1400    /// Otherwise, returns `true`.
1401    ///
1402    /// [`self.parent`]: Path::parent
1403    ///
1404    /// # Examples
1405    ///
1406    /// ```
1407    /// use std::path::{Path, PathBuf};
1408    ///
1409    /// let mut p = PathBuf::from("/spirited/away.rs");
1410    ///
1411    /// p.pop();
1412    /// assert_eq!(Path::new("/spirited"), p);
1413    /// p.pop();
1414    /// assert_eq!(Path::new("/"), p);
1415    /// ```
1416    #[stable(feature = "rust1", since = "1.0.0")]
1417    pub fn pop(&mut self) -> bool {
1418        match self.parent().map(|p| p.as_u8_slice().len()) {
1419            Some(len) => {
1420                self.inner.truncate(len);
1421                true
1422            }
1423            None => false,
1424        }
1425    }
1426
1427    /// Sets whether the path has a trailing [separator](MAIN_SEPARATOR).
1428    ///
1429    /// The value returned by [`has_trailing_sep`](Path::has_trailing_sep) will be equivalent to
1430    /// the provided value if possible.
1431    ///
1432    /// # Examples
1433    ///
1434    /// ```
1435    /// #![feature(path_trailing_sep)]
1436    /// use std::path::PathBuf;
1437    ///
1438    /// let mut p = PathBuf::from("dir");
1439    ///
1440    /// assert!(!p.has_trailing_sep());
1441    /// p.set_trailing_sep(false);
1442    /// assert!(!p.has_trailing_sep());
1443    /// p.set_trailing_sep(true);
1444    /// assert!(p.has_trailing_sep());
1445    /// p.set_trailing_sep(false);
1446    /// assert!(!p.has_trailing_sep());
1447    ///
1448    /// p = PathBuf::from("/");
1449    /// assert!(p.has_trailing_sep());
1450    /// p.set_trailing_sep(false);
1451    /// assert!(p.has_trailing_sep());
1452    /// ```
1453    #[unstable(feature = "path_trailing_sep", issue = "142503")]
1454    pub fn set_trailing_sep(&mut self, trailing_sep: bool) {
1455        if trailing_sep { self.push_trailing_sep() } else { self.pop_trailing_sep() }
1456    }
1457
1458    /// Adds a trailing [separator](MAIN_SEPARATOR) to the path.
1459    ///
1460    /// This acts similarly to [`Path::with_trailing_sep`], but mutates the underlying `PathBuf`.
1461    ///
1462    /// # Examples
1463    ///
1464    /// ```
1465    /// #![feature(path_trailing_sep)]
1466    /// use std::ffi::OsStr;
1467    /// use std::path::PathBuf;
1468    ///
1469    /// let mut p = PathBuf::from("dir");
1470    ///
1471    /// assert!(!p.has_trailing_sep());
1472    /// p.push_trailing_sep();
1473    /// assert!(p.has_trailing_sep());
1474    /// p.push_trailing_sep();
1475    /// assert!(p.has_trailing_sep());
1476    ///
1477    /// p = PathBuf::from("dir/");
1478    /// p.push_trailing_sep();
1479    /// assert_eq!(p.as_os_str(), OsStr::new("dir/"));
1480    /// ```
1481    #[unstable(feature = "path_trailing_sep", issue = "142503")]
1482    pub fn push_trailing_sep(&mut self) {
1483        if !self.has_trailing_sep() {
1484            self.push("");
1485        }
1486    }
1487
1488    /// Removes a trailing [separator](MAIN_SEPARATOR) from the path, if possible.
1489    ///
1490    /// This acts similarly to [`Path::trim_trailing_sep`], but mutates the underlying `PathBuf`.
1491    ///
1492    /// # Examples
1493    ///
1494    /// ```
1495    /// #![feature(path_trailing_sep)]
1496    /// use std::ffi::OsStr;
1497    /// use std::path::PathBuf;
1498    ///
1499    /// let mut p = PathBuf::from("dir//");
1500    ///
1501    /// assert!(p.has_trailing_sep());
1502    /// assert_eq!(p.as_os_str(), OsStr::new("dir//"));
1503    /// p.pop_trailing_sep();
1504    /// assert!(!p.has_trailing_sep());
1505    /// assert_eq!(p.as_os_str(), OsStr::new("dir"));
1506    /// p.pop_trailing_sep();
1507    /// assert!(!p.has_trailing_sep());
1508    /// assert_eq!(p.as_os_str(), OsStr::new("dir"));
1509    ///
1510    /// p = PathBuf::from("/");
1511    /// assert!(p.has_trailing_sep());
1512    /// p.pop_trailing_sep();
1513    /// assert!(p.has_trailing_sep());
1514    /// ```
1515    #[unstable(feature = "path_trailing_sep", issue = "142503")]
1516    pub fn pop_trailing_sep(&mut self) {
1517        self.inner.truncate(self.trim_trailing_sep().as_os_str().len());
1518    }
1519
1520    /// Updates [`self.file_name`] to `file_name`.
1521    ///
1522    /// If [`self.file_name`] was [`None`], this is equivalent to pushing
1523    /// `file_name`.
1524    ///
1525    /// Otherwise it is equivalent to calling [`pop`] and then pushing
1526    /// `file_name`. The new path will be a sibling of the original path.
1527    /// (That is, it will have the same parent.)
1528    ///
1529    /// The argument is not sanitized, so can include separators. This
1530    /// behavior may be changed to a panic in the future.
1531    ///
1532    /// [`self.file_name`]: Path::file_name
1533    /// [`pop`]: PathBuf::pop
1534    ///
1535    /// # Examples
1536    ///
1537    /// ```
1538    /// use std::path::PathBuf;
1539    ///
1540    /// let mut buf = PathBuf::from("/");
1541    /// assert!(buf.file_name() == None);
1542    ///
1543    /// buf.set_file_name("foo.txt");
1544    /// assert!(buf == PathBuf::from("/foo.txt"));
1545    /// assert!(buf.file_name().is_some());
1546    ///
1547    /// buf.set_file_name("bar.txt");
1548    /// assert!(buf == PathBuf::from("/bar.txt"));
1549    ///
1550    /// buf.set_file_name("baz");
1551    /// assert!(buf == PathBuf::from("/baz"));
1552    ///
1553    /// buf.set_file_name("../b/c.txt");
1554    /// assert!(buf == PathBuf::from("/../b/c.txt"));
1555    ///
1556    /// buf.set_file_name("baz");
1557    /// assert!(buf == PathBuf::from("/../b/baz"));
1558    /// ```
1559    #[stable(feature = "rust1", since = "1.0.0")]
1560    pub fn set_file_name<S: AsRef<OsStr>>(&mut self, file_name: S) {
1561        self._set_file_name(file_name.as_ref())
1562    }
1563
1564    fn _set_file_name(&mut self, file_name: &OsStr) {
1565        if self.file_name().is_some() {
1566            let popped = self.pop();
1567            debug_assert!(popped);
1568        }
1569        self.push(file_name);
1570    }
1571
1572    /// Updates [`self.extension`] to `Some(extension)` or to `None` if
1573    /// `extension` is empty.
1574    ///
1575    /// Returns `false` and does nothing if [`self.file_name`] is [`None`],
1576    /// returns `true` and updates the extension otherwise.
1577    ///
1578    /// If [`self.extension`] is [`None`], the extension is added; otherwise
1579    /// it is replaced.
1580    ///
1581    /// If `extension` is the empty string, [`self.extension`] will be [`None`]
1582    /// afterwards, not `Some("")`.
1583    ///
1584    /// # Panics
1585    ///
1586    /// Panics if the passed extension contains a path separator (see
1587    /// [`is_separator`]).
1588    ///
1589    /// # Caveats
1590    ///
1591    /// The new `extension` may contain dots and will be used in its entirety,
1592    /// but only the part after the final dot will be reflected in
1593    /// [`self.extension`].
1594    ///
1595    /// If the file stem contains internal dots and `extension` is empty, part
1596    /// of the old file stem will be considered the new [`self.extension`].
1597    ///
1598    /// See the examples below.
1599    ///
1600    /// [`self.file_name`]: Path::file_name
1601    /// [`self.extension`]: Path::extension
1602    ///
1603    /// # Examples
1604    ///
1605    /// ```
1606    /// use std::path::{Path, PathBuf};
1607    ///
1608    /// let mut p = PathBuf::from("/feel/the");
1609    ///
1610    /// p.set_extension("force");
1611    /// assert_eq!(Path::new("/feel/the.force"), p.as_path());
1612    ///
1613    /// p.set_extension("dark.side");
1614    /// assert_eq!(Path::new("/feel/the.dark.side"), p.as_path());
1615    ///
1616    /// p.set_extension("cookie");
1617    /// assert_eq!(Path::new("/feel/the.dark.cookie"), p.as_path());
1618    ///
1619    /// p.set_extension("");
1620    /// assert_eq!(Path::new("/feel/the.dark"), p.as_path());
1621    ///
1622    /// p.set_extension("");
1623    /// assert_eq!(Path::new("/feel/the"), p.as_path());
1624    ///
1625    /// p.set_extension("");
1626    /// assert_eq!(Path::new("/feel/the"), p.as_path());
1627    /// ```
1628    #[stable(feature = "rust1", since = "1.0.0")]
1629    pub fn set_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
1630        self._set_extension(extension.as_ref())
1631    }
1632
1633    fn _set_extension(&mut self, extension: &OsStr) -> bool {
1634        validate_extension(extension);
1635
1636        let file_stem = match self.file_stem() {
1637            None => return false,
1638            Some(f) => f.as_encoded_bytes(),
1639        };
1640
1641        // truncate until right after the file stem
1642        let end_file_stem = file_stem[file_stem.len()..].as_ptr().addr();
1643        let start = self.inner.as_encoded_bytes().as_ptr().addr();
1644        self.inner.truncate(end_file_stem.wrapping_sub(start));
1645
1646        // add the new extension, if any
1647        let new = extension.as_encoded_bytes();
1648        if !new.is_empty() {
1649            self.inner.reserve_exact(new.len() + 1);
1650            self.inner.push(".");
1651            // SAFETY: Since a UTF-8 string was just pushed, it is not possible
1652            // for the buffer to end with a surrogate half.
1653            unsafe { self.inner.extend_from_slice_unchecked(new) };
1654        }
1655
1656        true
1657    }
1658
1659    /// Append [`self.extension`] with `extension`.
1660    ///
1661    /// Returns `false` and does nothing if [`self.file_name`] is [`None`],
1662    /// returns `true` and updates the extension otherwise.
1663    ///
1664    /// # Panics
1665    ///
1666    /// Panics if the passed extension contains a path separator (see
1667    /// [`is_separator`]).
1668    ///
1669    /// # Caveats
1670    ///
1671    /// The appended `extension` may contain dots and will be used in its entirety,
1672    /// but only the part after the final dot will be reflected in
1673    /// [`self.extension`].
1674    ///
1675    /// See the examples below.
1676    ///
1677    /// [`self.file_name`]: Path::file_name
1678    /// [`self.extension`]: Path::extension
1679    ///
1680    /// # Examples
1681    ///
1682    /// ```
1683    /// use std::path::{Path, PathBuf};
1684    ///
1685    /// let mut p = PathBuf::from("/feel/the");
1686    ///
1687    /// p.add_extension("formatted");
1688    /// assert_eq!(Path::new("/feel/the.formatted"), p.as_path());
1689    ///
1690    /// p.add_extension("dark.side");
1691    /// assert_eq!(Path::new("/feel/the.formatted.dark.side"), p.as_path());
1692    ///
1693    /// p.set_extension("cookie");
1694    /// assert_eq!(Path::new("/feel/the.formatted.dark.cookie"), p.as_path());
1695    ///
1696    /// p.set_extension("");
1697    /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
1698    ///
1699    /// p.add_extension("");
1700    /// assert_eq!(Path::new("/feel/the.formatted.dark"), p.as_path());
1701    /// ```
1702    #[stable(feature = "path_add_extension", since = "1.91.0")]
1703    pub fn add_extension<S: AsRef<OsStr>>(&mut self, extension: S) -> bool {
1704        self._add_extension(extension.as_ref())
1705    }
1706
1707    fn _add_extension(&mut self, extension: &OsStr) -> bool {
1708        validate_extension(extension);
1709
1710        let file_name = match self.file_name() {
1711            None => return false,
1712            Some(f) => f.as_encoded_bytes(),
1713        };
1714
1715        let new = extension.as_encoded_bytes();
1716        if !new.is_empty() {
1717            // truncate until right after the file name
1718            // this is necessary for trimming the trailing separator
1719            let end_file_name = file_name[file_name.len()..].as_ptr().addr();
1720            let start = self.inner.as_encoded_bytes().as_ptr().addr();
1721            self.inner.truncate(end_file_name.wrapping_sub(start));
1722
1723            // append the new extension
1724            self.inner.reserve_exact(new.len() + 1);
1725            self.inner.push(".");
1726            // SAFETY: Since a UTF-8 string was just pushed, it is not possible
1727            // for the buffer to end with a surrogate half.
1728            unsafe { self.inner.extend_from_slice_unchecked(new) };
1729        }
1730
1731        true
1732    }
1733
1734    /// Yields a mutable reference to the underlying [`OsString`] instance.
1735    ///
1736    /// # Examples
1737    ///
1738    /// ```
1739    /// use std::path::{Path, PathBuf};
1740    ///
1741    /// let mut path = PathBuf::from("/foo");
1742    ///
1743    /// path.push("bar");
1744    /// assert_eq!(path, Path::new("/foo/bar"));
1745    ///
1746    /// // OsString's `push` does not add a separator.
1747    /// path.as_mut_os_string().push("baz");
1748    /// assert_eq!(path, Path::new("/foo/barbaz"));
1749    /// ```
1750    #[stable(feature = "path_as_mut_os_str", since = "1.70.0")]
1751    #[must_use]
1752    #[inline]
1753    pub fn as_mut_os_string(&mut self) -> &mut OsString {
1754        &mut self.inner
1755    }
1756
1757    /// Consumes the `PathBuf`, yielding its internal [`OsString`] storage.
1758    ///
1759    /// # Examples
1760    ///
1761    /// ```
1762    /// use std::path::PathBuf;
1763    ///
1764    /// let p = PathBuf::from("/the/head");
1765    /// let os_str = p.into_os_string();
1766    /// ```
1767    #[stable(feature = "rust1", since = "1.0.0")]
1768    #[must_use = "`self` will be dropped if the result is not used"]
1769    #[inline]
1770    pub fn into_os_string(self) -> OsString {
1771        self.inner
1772    }
1773
1774    /// Converts this `PathBuf` into a [boxed](Box) [`Path`].
1775    #[stable(feature = "into_boxed_path", since = "1.20.0")]
1776    #[must_use = "`self` will be dropped if the result is not used"]
1777    #[inline]
1778    pub fn into_boxed_path(self) -> Box<Path> {
1779        let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path;
1780        unsafe { Box::from_raw(rw) }
1781    }
1782
1783    /// Invokes [`capacity`] on the underlying instance of [`OsString`].
1784    ///
1785    /// [`capacity`]: OsString::capacity
1786    #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1787    #[must_use]
1788    #[inline]
1789    pub fn capacity(&self) -> usize {
1790        self.inner.capacity()
1791    }
1792
1793    /// Invokes [`clear`] on the underlying instance of [`OsString`].
1794    ///
1795    /// [`clear`]: OsString::clear
1796    #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1797    #[inline]
1798    pub fn clear(&mut self) {
1799        self.inner.clear()
1800    }
1801
1802    /// Invokes [`reserve`] on the underlying instance of [`OsString`].
1803    ///
1804    /// [`reserve`]: OsString::reserve
1805    #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1806    #[inline]
1807    pub fn reserve(&mut self, additional: usize) {
1808        self.inner.reserve(additional)
1809    }
1810
1811    /// Invokes [`try_reserve`] on the underlying instance of [`OsString`].
1812    ///
1813    /// [`try_reserve`]: OsString::try_reserve
1814    #[stable(feature = "try_reserve_2", since = "1.63.0")]
1815    #[inline]
1816    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
1817        self.inner.try_reserve(additional)
1818    }
1819
1820    /// Invokes [`reserve_exact`] on the underlying instance of [`OsString`].
1821    ///
1822    /// [`reserve_exact`]: OsString::reserve_exact
1823    #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1824    #[inline]
1825    pub fn reserve_exact(&mut self, additional: usize) {
1826        self.inner.reserve_exact(additional)
1827    }
1828
1829    /// Invokes [`try_reserve_exact`] on the underlying instance of [`OsString`].
1830    ///
1831    /// [`try_reserve_exact`]: OsString::try_reserve_exact
1832    #[stable(feature = "try_reserve_2", since = "1.63.0")]
1833    #[inline]
1834    pub fn try_reserve_exact(&mut self, additional: usize) -> Result<(), TryReserveError> {
1835        self.inner.try_reserve_exact(additional)
1836    }
1837
1838    /// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`].
1839    ///
1840    /// [`shrink_to_fit`]: OsString::shrink_to_fit
1841    #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1842    #[inline]
1843    pub fn shrink_to_fit(&mut self) {
1844        self.inner.shrink_to_fit()
1845    }
1846
1847    /// Invokes [`shrink_to`] on the underlying instance of [`OsString`].
1848    ///
1849    /// [`shrink_to`]: OsString::shrink_to
1850    #[stable(feature = "shrink_to", since = "1.56.0")]
1851    #[inline]
1852    pub fn shrink_to(&mut self, min_capacity: usize) {
1853        self.inner.shrink_to(min_capacity)
1854    }
1855}
1856
1857#[stable(feature = "rust1", since = "1.0.0")]
1858impl Clone for PathBuf {
1859    #[inline]
1860    fn clone(&self) -> Self {
1861        PathBuf { inner: self.inner.clone() }
1862    }
1863
1864    /// Clones the contents of `source` into `self`.
1865    ///
1866    /// This method is preferred over simply assigning `source.clone()` to `self`,
1867    /// as it avoids reallocation if possible.
1868    #[inline]
1869    fn clone_from(&mut self, source: &Self) {
1870        self.inner.clone_from(&source.inner)
1871    }
1872}
1873
1874#[stable(feature = "box_from_path", since = "1.17.0")]
1875impl From<&Path> for Box<Path> {
1876    /// Creates a boxed [`Path`] from a reference.
1877    ///
1878    /// This will allocate and clone `path` to it.
1879    fn from(path: &Path) -> Box<Path> {
1880        let boxed: Box<OsStr> = path.inner.into();
1881        let rw = Box::into_raw(boxed) as *mut Path;
1882        unsafe { Box::from_raw(rw) }
1883    }
1884}
1885
1886#[stable(feature = "box_from_mut_slice", since = "1.84.0")]
1887impl From<&mut Path> for Box<Path> {
1888    /// Creates a boxed [`Path`] from a reference.
1889    ///
1890    /// This will allocate and clone `path` to it.
1891    fn from(path: &mut Path) -> Box<Path> {
1892        Self::from(&*path)
1893    }
1894}
1895
1896#[stable(feature = "box_from_cow", since = "1.45.0")]
1897impl From<Cow<'_, Path>> for Box<Path> {
1898    /// Creates a boxed [`Path`] from a clone-on-write pointer.
1899    ///
1900    /// Converting from a `Cow::Owned` does not clone or allocate.
1901    #[inline]
1902    fn from(cow: Cow<'_, Path>) -> Box<Path> {
1903        match cow {
1904            Cow::Borrowed(path) => Box::from(path),
1905            Cow::Owned(path) => Box::from(path),
1906        }
1907    }
1908}
1909
1910#[stable(feature = "path_buf_from_box", since = "1.18.0")]
1911impl From<Box<Path>> for PathBuf {
1912    /// Converts a <code>[Box]&lt;[Path]&gt;</code> into a [`PathBuf`].
1913    ///
1914    /// This conversion does not allocate or copy memory.
1915    #[inline]
1916    fn from(boxed: Box<Path>) -> PathBuf {
1917        boxed.into_path_buf()
1918    }
1919}
1920
1921#[stable(feature = "box_from_path_buf", since = "1.20.0")]
1922impl From<PathBuf> for Box<Path> {
1923    /// Converts a [`PathBuf`] into a <code>[Box]&lt;[Path]&gt;</code>.
1924    ///
1925    /// This conversion currently should not allocate memory,
1926    /// but this behavior is not guaranteed on all platforms or in all future versions.
1927    #[inline]
1928    fn from(p: PathBuf) -> Box<Path> {
1929        p.into_boxed_path()
1930    }
1931}
1932
1933#[stable(feature = "more_box_slice_clone", since = "1.29.0")]
1934impl Clone for Box<Path> {
1935    #[inline]
1936    fn clone(&self) -> Self {
1937        self.to_path_buf().into_boxed_path()
1938    }
1939}
1940
1941#[stable(feature = "rust1", since = "1.0.0")]
1942impl<T: ?Sized + AsRef<OsStr>> From<&T> for PathBuf {
1943    /// Converts a borrowed [`OsStr`] to a [`PathBuf`].
1944    ///
1945    /// Allocates a [`PathBuf`] and copies the data into it.
1946    #[inline]
1947    fn from(s: &T) -> PathBuf {
1948        PathBuf::from(s.as_ref().to_os_string())
1949    }
1950}
1951
1952#[stable(feature = "rust1", since = "1.0.0")]
1953impl From<OsString> for PathBuf {
1954    /// Converts an [`OsString`] into a [`PathBuf`].
1955    ///
1956    /// This conversion does not allocate or copy memory.
1957    #[inline]
1958    fn from(s: OsString) -> PathBuf {
1959        PathBuf { inner: s }
1960    }
1961}
1962
1963#[stable(feature = "from_path_buf_for_os_string", since = "1.14.0")]
1964impl From<PathBuf> for OsString {
1965    /// Converts a [`PathBuf`] into an [`OsString`]
1966    ///
1967    /// This conversion does not allocate or copy memory.
1968    #[inline]
1969    fn from(path_buf: PathBuf) -> OsString {
1970        path_buf.inner
1971    }
1972}
1973
1974#[stable(feature = "rust1", since = "1.0.0")]
1975impl From<String> for PathBuf {
1976    /// Converts a [`String`] into a [`PathBuf`]
1977    ///
1978    /// This conversion does not allocate or copy memory.
1979    #[inline]
1980    fn from(s: String) -> PathBuf {
1981        PathBuf::from(OsString::from(s))
1982    }
1983}
1984
1985#[stable(feature = "path_from_str", since = "1.32.0")]
1986impl FromStr for PathBuf {
1987    type Err = core::convert::Infallible;
1988
1989    #[inline]
1990    fn from_str(s: &str) -> Result<Self, Self::Err> {
1991        Ok(PathBuf::from(s))
1992    }
1993}
1994
1995#[stable(feature = "rust1", since = "1.0.0")]
1996impl<P: AsRef<Path>> FromIterator<P> for PathBuf {
1997    /// Creates a new `PathBuf` from the [`Path`] elements of an iterator.
1998    ///
1999    /// This uses [`push`](Self::push) to add each element, so can be used to adjoin multiple path
2000    /// [components](Components).
2001    ///
2002    /// # Examples
2003    /// ```
2004    /// # use std::path::PathBuf;
2005    /// let path = PathBuf::from_iter(["/tmp", "foo", "bar"]);
2006    /// assert_eq!(path, PathBuf::from("/tmp/foo/bar"));
2007    /// ```
2008    ///
2009    /// See documentation for [`push`](Self::push) for more details on how the path is constructed.
2010    fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
2011        let mut buf = PathBuf::new();
2012        buf.extend(iter);
2013        buf
2014    }
2015}
2016
2017#[stable(feature = "rust1", since = "1.0.0")]
2018impl<P: AsRef<Path>> Extend<P> for PathBuf {
2019    /// Extends `self` with [`Path`] elements from `iter`.
2020    ///
2021    /// This uses [`push`](Self::push) to add each element, so can be used to adjoin multiple path
2022    /// [components](Components).
2023    ///
2024    /// # Examples
2025    /// ```
2026    /// # use std::path::PathBuf;
2027    /// let mut path = PathBuf::from("/tmp");
2028    /// path.extend(["foo", "bar", "file.txt"]);
2029    /// assert_eq!(path, PathBuf::from("/tmp/foo/bar/file.txt"));
2030    /// ```
2031    ///
2032    /// See documentation for [`push`](Self::push) for more details on how the path is constructed.
2033    fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
2034        iter.into_iter().for_each(move |p| self.push(p.as_ref()));
2035    }
2036
2037    #[inline]
2038    fn extend_one(&mut self, p: P) {
2039        self.push(p.as_ref());
2040    }
2041}
2042
2043#[stable(feature = "rust1", since = "1.0.0")]
2044impl fmt::Debug for PathBuf {
2045    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
2046        fmt::Debug::fmt(&**self, formatter)
2047    }
2048}
2049
2050#[stable(feature = "rust1", since = "1.0.0")]
2051impl ops::Deref for PathBuf {
2052    type Target = Path;
2053    #[inline]
2054    fn deref(&self) -> &Path {
2055        Path::new(&self.inner)
2056    }
2057}
2058
2059#[stable(feature = "path_buf_deref_mut", since = "1.68.0")]
2060impl ops::DerefMut for PathBuf {
2061    #[inline]
2062    fn deref_mut(&mut self) -> &mut Path {
2063        Path::from_inner_mut(&mut self.inner)
2064    }
2065}
2066
2067#[stable(feature = "rust1", since = "1.0.0")]
2068impl Borrow<Path> for PathBuf {
2069    #[inline]
2070    fn borrow(&self) -> &Path {
2071        self.deref()
2072    }
2073}
2074
2075#[stable(feature = "default_for_pathbuf", since = "1.17.0")]
2076impl Default for PathBuf {
2077    #[inline]
2078    fn default() -> Self {
2079        PathBuf::new()
2080    }
2081}
2082
2083#[stable(feature = "cow_from_path", since = "1.6.0")]
2084impl<'a> From<&'a Path> for Cow<'a, Path> {
2085    /// Creates a clone-on-write pointer from a reference to
2086    /// [`Path`].
2087    ///
2088    /// This conversion does not clone or allocate.
2089    #[inline]
2090    fn from(s: &'a Path) -> Cow<'a, Path> {
2091        Cow::Borrowed(s)
2092    }
2093}
2094
2095#[stable(feature = "cow_from_path", since = "1.6.0")]
2096impl<'a> From<PathBuf> for Cow<'a, Path> {
2097    /// Creates a clone-on-write pointer from an owned
2098    /// instance of [`PathBuf`].
2099    ///
2100    /// This conversion does not clone or allocate.
2101    #[inline]
2102    fn from(s: PathBuf) -> Cow<'a, Path> {
2103        Cow::Owned(s)
2104    }
2105}
2106
2107#[stable(feature = "cow_from_pathbuf_ref", since = "1.28.0")]
2108impl<'a> From<&'a PathBuf> for Cow<'a, Path> {
2109    /// Creates a clone-on-write pointer from a reference to
2110    /// [`PathBuf`].
2111    ///
2112    /// This conversion does not clone or allocate.
2113    #[inline]
2114    fn from(p: &'a PathBuf) -> Cow<'a, Path> {
2115        Cow::Borrowed(p.as_path())
2116    }
2117}
2118
2119#[stable(feature = "pathbuf_from_cow_path", since = "1.28.0")]
2120impl<'a> From<Cow<'a, Path>> for PathBuf {
2121    /// Converts a clone-on-write pointer to an owned path.
2122    ///
2123    /// Converting from a `Cow::Owned` does not clone or allocate.
2124    #[inline]
2125    fn from(p: Cow<'a, Path>) -> Self {
2126        p.into_owned()
2127    }
2128}
2129
2130#[stable(feature = "shared_from_slice2", since = "1.24.0")]
2131impl From<PathBuf> for Arc<Path> {
2132    /// Converts a [`PathBuf`] into an <code>[Arc]<[Path]></code> by moving the [`PathBuf`] data
2133    /// into a new [`Arc`] buffer.
2134    #[inline]
2135    fn from(s: PathBuf) -> Arc<Path> {
2136        let arc: Arc<OsStr> = Arc::from(s.into_os_string());
2137        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) }
2138    }
2139}
2140
2141#[stable(feature = "shared_from_slice2", since = "1.24.0")]
2142impl From<&Path> for Arc<Path> {
2143    /// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer.
2144    #[inline]
2145    fn from(s: &Path) -> Arc<Path> {
2146        let arc: Arc<OsStr> = Arc::from(s.as_os_str());
2147        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) }
2148    }
2149}
2150
2151#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
2152impl From<&mut Path> for Arc<Path> {
2153    /// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer.
2154    #[inline]
2155    fn from(s: &mut Path) -> Arc<Path> {
2156        Arc::from(&*s)
2157    }
2158}
2159
2160#[stable(feature = "shared_from_slice2", since = "1.24.0")]
2161impl From<PathBuf> for Rc<Path> {
2162    /// Converts a [`PathBuf`] into an <code>[Rc]<[Path]></code> by moving the [`PathBuf`] data into
2163    /// a new [`Rc`] buffer.
2164    #[inline]
2165    fn from(s: PathBuf) -> Rc<Path> {
2166        let rc: Rc<OsStr> = Rc::from(s.into_os_string());
2167        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) }
2168    }
2169}
2170
2171#[stable(feature = "shared_from_slice2", since = "1.24.0")]
2172impl From<&Path> for Rc<Path> {
2173    /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer.
2174    #[inline]
2175    fn from(s: &Path) -> Rc<Path> {
2176        let rc: Rc<OsStr> = Rc::from(s.as_os_str());
2177        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) }
2178    }
2179}
2180
2181#[stable(feature = "shared_from_mut_slice", since = "1.84.0")]
2182impl From<&mut Path> for Rc<Path> {
2183    /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new [`Rc`] buffer.
2184    #[inline]
2185    fn from(s: &mut Path) -> Rc<Path> {
2186        Rc::from(&*s)
2187    }
2188}
2189
2190#[stable(feature = "rust1", since = "1.0.0")]
2191impl ToOwned for Path {
2192    type Owned = PathBuf;
2193    #[inline]
2194    fn to_owned(&self) -> PathBuf {
2195        self.to_path_buf()
2196    }
2197    #[inline]
2198    fn clone_into(&self, target: &mut PathBuf) {
2199        self.inner.clone_into(&mut target.inner);
2200    }
2201}
2202
2203#[stable(feature = "rust1", since = "1.0.0")]
2204impl PartialEq for PathBuf {
2205    #[inline]
2206    fn eq(&self, other: &PathBuf) -> bool {
2207        self.components() == other.components()
2208    }
2209}
2210
2211#[stable(feature = "eq_str_for_path", since = "1.91.0")]
2212impl cmp::PartialEq<str> for PathBuf {
2213    #[inline]
2214    fn eq(&self, other: &str) -> bool {
2215        self.as_path() == other
2216    }
2217}
2218
2219#[stable(feature = "eq_str_for_path", since = "1.91.0")]
2220impl cmp::PartialEq<PathBuf> for str {
2221    #[inline]
2222    fn eq(&self, other: &PathBuf) -> bool {
2223        self == other.as_path()
2224    }
2225}
2226
2227#[stable(feature = "eq_str_for_path", since = "1.91.0")]
2228impl cmp::PartialEq<String> for PathBuf {
2229    #[inline]
2230    fn eq(&self, other: &String) -> bool {
2231        self.as_path() == other.as_str()
2232    }
2233}
2234
2235#[stable(feature = "eq_str_for_path", since = "1.91.0")]
2236impl cmp::PartialEq<PathBuf> for String {
2237    #[inline]
2238    fn eq(&self, other: &PathBuf) -> bool {
2239        self.as_str() == other.as_path()
2240    }
2241}
2242
2243#[stable(feature = "rust1", since = "1.0.0")]
2244impl Hash for PathBuf {
2245    fn hash<H: Hasher>(&self, h: &mut H) {
2246        self.as_path().hash(h)
2247    }
2248}
2249
2250#[stable(feature = "rust1", since = "1.0.0")]
2251impl Eq for PathBuf {}
2252
2253#[stable(feature = "rust1", since = "1.0.0")]
2254impl PartialOrd for PathBuf {
2255    #[inline]
2256    fn partial_cmp(&self, other: &PathBuf) -> Option<cmp::Ordering> {
2257        Some(compare_components(self.components(), other.components()))
2258    }
2259}
2260
2261#[stable(feature = "rust1", since = "1.0.0")]
2262impl Ord for PathBuf {
2263    #[inline]
2264    fn cmp(&self, other: &PathBuf) -> cmp::Ordering {
2265        compare_components(self.components(), other.components())
2266    }
2267}
2268
2269#[stable(feature = "rust1", since = "1.0.0")]
2270impl AsRef<OsStr> for PathBuf {
2271    #[inline]
2272    fn as_ref(&self) -> &OsStr {
2273        &self.inner[..]
2274    }
2275}
2276
2277/// A slice of a path (akin to [`str`]).
2278///
2279/// This type supports a number of operations for inspecting a path, including
2280/// breaking the path into its components (separated by `/` on Unix and by either
2281/// `/` or `\` on Windows), extracting the file name, determining whether the path
2282/// is absolute, and so on.
2283///
2284/// This is an *unsized* type, meaning that it must always be used behind a
2285/// pointer like `&` or [`Box`]. For an owned version of this type,
2286/// see [`PathBuf`].
2287///
2288/// More details about the overall approach can be found in
2289/// the [module documentation](self).
2290///
2291/// # Examples
2292///
2293/// ```
2294/// use std::path::Path;
2295/// use std::ffi::OsStr;
2296///
2297/// // Note: this example does work on Windows
2298/// let path = Path::new("./foo/bar.txt");
2299///
2300/// let parent = path.parent();
2301/// assert_eq!(parent, Some(Path::new("./foo")));
2302///
2303/// let file_stem = path.file_stem();
2304/// assert_eq!(file_stem, Some(OsStr::new("bar")));
2305///
2306/// let extension = path.extension();
2307/// assert_eq!(extension, Some(OsStr::new("txt")));
2308/// ```
2309#[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
2310#[stable(feature = "rust1", since = "1.0.0")]
2311// `Path::new` and `impl CloneToUninit for Path` current implementation relies
2312// on `Path` being layout-compatible with `OsStr`.
2313// However, `Path` layout is considered an implementation detail and must not be relied upon.
2314#[repr(transparent)]
2315pub struct Path {
2316    inner: OsStr,
2317}
2318
2319/// An error returned from [`Path::strip_prefix`] if the prefix was not found.
2320///
2321/// This `struct` is created by the [`strip_prefix`] method on [`Path`].
2322/// See its documentation for more.
2323///
2324/// [`strip_prefix`]: Path::strip_prefix
2325#[derive(Debug, Clone, PartialEq, Eq)]
2326#[stable(since = "1.7.0", feature = "strip_prefix")]
2327pub struct StripPrefixError(());
2328
2329/// An error returned from [`Path::normalize_lexically`] if a `..` parent reference
2330/// would escape the path.
2331#[unstable(feature = "normalize_lexically", issue = "134694")]
2332#[derive(Debug, PartialEq)]
2333#[non_exhaustive]
2334pub struct NormalizeError;
2335
2336impl Path {
2337    // The following (private!) function allows construction of a path from a u8
2338    // slice, which is only safe when it is known to follow the OsStr encoding.
2339    unsafe fn from_u8_slice(s: &[u8]) -> &Path {
2340        unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) }
2341    }
2342    // The following (private!) function reveals the byte encoding used for OsStr.
2343    pub(crate) fn as_u8_slice(&self) -> &[u8] {
2344        self.inner.as_encoded_bytes()
2345    }
2346
2347    /// Directly wraps a string slice as a `Path` slice.
2348    ///
2349    /// This is a cost-free conversion.
2350    ///
2351    /// # Examples
2352    ///
2353    /// ```
2354    /// use std::path::Path;
2355    ///
2356    /// Path::new("foo.txt");
2357    /// ```
2358    ///
2359    /// You can create `Path`s from `String`s, or even other `Path`s:
2360    ///
2361    /// ```
2362    /// use std::path::Path;
2363    ///
2364    /// let string = String::from("foo.txt");
2365    /// let from_string = Path::new(&string);
2366    /// let from_path = Path::new(&from_string);
2367    /// assert_eq!(from_string, from_path);
2368    /// ```
2369    #[stable(feature = "rust1", since = "1.0.0")]
2370    #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2371    pub const fn new<S: [const] AsRef<OsStr> + ?Sized>(s: &S) -> &Path {
2372        unsafe { &*(s.as_ref() as *const OsStr as *const Path) }
2373    }
2374
2375    #[rustc_const_unstable(feature = "const_convert", issue = "143773")]
2376    const fn from_inner_mut(inner: &mut OsStr) -> &mut Path {
2377        // SAFETY: Path is just a wrapper around OsStr,
2378        // therefore converting &mut OsStr to &mut Path is safe.
2379        unsafe { &mut *(inner as *mut OsStr as *mut Path) }
2380    }
2381
2382    /// Yields the underlying [`OsStr`] slice.
2383    ///
2384    /// # Examples
2385    ///
2386    /// ```
2387    /// use std::path::Path;
2388    ///
2389    /// let os_str = Path::new("foo.txt").as_os_str();
2390    /// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt"));
2391    /// ```
2392    #[stable(feature = "rust1", since = "1.0.0")]
2393    #[must_use]
2394    #[inline]
2395    pub fn as_os_str(&self) -> &OsStr {
2396        &self.inner
2397    }
2398
2399    /// Yields a mutable reference to the underlying [`OsStr`] slice.
2400    ///
2401    /// # Examples
2402    ///
2403    /// ```
2404    /// use std::path::{Path, PathBuf};
2405    ///
2406    /// let mut path = PathBuf::from("Foo.TXT");
2407    ///
2408    /// assert_ne!(path, Path::new("foo.txt"));
2409    ///
2410    /// path.as_mut_os_str().make_ascii_lowercase();
2411    /// assert_eq!(path, Path::new("foo.txt"));
2412    /// ```
2413    #[stable(feature = "path_as_mut_os_str", since = "1.70.0")]
2414    #[must_use]
2415    #[inline]
2416    pub fn as_mut_os_str(&mut self) -> &mut OsStr {
2417        &mut self.inner
2418    }
2419
2420    /// Yields a [`&str`] slice if the `Path` is valid unicode.
2421    ///
2422    /// This conversion may entail doing a check for UTF-8 validity.
2423    /// Note that validation is performed because non-UTF-8 strings are
2424    /// perfectly valid for some OS.
2425    ///
2426    /// [`&str`]: str
2427    ///
2428    /// # Examples
2429    ///
2430    /// ```
2431    /// use std::path::Path;
2432    ///
2433    /// let path = Path::new("foo.txt");
2434    /// assert_eq!(path.to_str(), Some("foo.txt"));
2435    /// ```
2436    #[stable(feature = "rust1", since = "1.0.0")]
2437    #[must_use = "this returns the result of the operation, \
2438                  without modifying the original"]
2439    #[inline]
2440    pub fn to_str(&self) -> Option<&str> {
2441        self.inner.to_str()
2442    }
2443
2444    /// Converts a `Path` to a [`Cow<str>`].
2445    ///
2446    /// Any non-UTF-8 sequences are replaced with
2447    /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
2448    ///
2449    /// [U+FFFD]: super::char::REPLACEMENT_CHARACTER
2450    ///
2451    /// # Examples
2452    ///
2453    /// Calling `to_string_lossy` on a `Path` with valid unicode:
2454    ///
2455    /// ```
2456    /// use std::path::Path;
2457    ///
2458    /// let path = Path::new("foo.txt");
2459    /// assert_eq!(path.to_string_lossy(), "foo.txt");
2460    /// ```
2461    ///
2462    /// Had `path` contained invalid unicode, the `to_string_lossy` call might
2463    /// have returned `"fo�.txt"`.
2464    #[stable(feature = "rust1", since = "1.0.0")]
2465    #[must_use = "this returns the result of the operation, \
2466                  without modifying the original"]
2467    #[inline]
2468    pub fn to_string_lossy(&self) -> Cow<'_, str> {
2469        self.inner.to_string_lossy()
2470    }
2471
2472    /// Converts a `Path` to an owned [`PathBuf`].
2473    ///
2474    /// # Examples
2475    ///
2476    /// ```
2477    /// use std::path::{Path, PathBuf};
2478    ///
2479    /// let path_buf = Path::new("foo.txt").to_path_buf();
2480    /// assert_eq!(path_buf, PathBuf::from("foo.txt"));
2481    /// ```
2482    #[rustc_conversion_suggestion]
2483    #[must_use = "this returns the result of the operation, \
2484                  without modifying the original"]
2485    #[stable(feature = "rust1", since = "1.0.0")]
2486    #[cfg_attr(not(test), rustc_diagnostic_item = "path_to_pathbuf")]
2487    pub fn to_path_buf(&self) -> PathBuf {
2488        PathBuf::from(self.inner.to_os_string())
2489    }
2490
2491    /// Returns `true` if the `Path` is absolute, i.e., if it is independent of
2492    /// the current directory.
2493    ///
2494    /// * On Unix, a path is absolute if it starts with the root, so
2495    /// `is_absolute` and [`has_root`] are equivalent.
2496    ///
2497    /// * On Windows, a path is absolute if it has a prefix and starts with the
2498    /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not.
2499    ///
2500    /// # Examples
2501    ///
2502    /// ```
2503    /// use std::path::Path;
2504    ///
2505    /// assert!(!Path::new("foo.txt").is_absolute());
2506    /// ```
2507    ///
2508    /// [`has_root`]: Path::has_root
2509    #[stable(feature = "rust1", since = "1.0.0")]
2510    #[must_use]
2511    #[allow(deprecated)]
2512    pub fn is_absolute(&self) -> bool {
2513        sys::path::is_absolute(self)
2514    }
2515
2516    /// Returns `true` if the `Path` is relative, i.e., not absolute.
2517    ///
2518    /// See [`is_absolute`]'s documentation for more details.
2519    ///
2520    /// # Examples
2521    ///
2522    /// ```
2523    /// use std::path::Path;
2524    ///
2525    /// assert!(Path::new("foo.txt").is_relative());
2526    /// ```
2527    ///
2528    /// [`is_absolute`]: Path::is_absolute
2529    #[stable(feature = "rust1", since = "1.0.0")]
2530    #[must_use]
2531    #[inline]
2532    pub fn is_relative(&self) -> bool {
2533        !self.is_absolute()
2534    }
2535
2536    pub(crate) fn prefix(&self) -> Option<Prefix<'_>> {
2537        self.components().prefix
2538    }
2539
2540    /// Returns `true` if the `Path` has a root.
2541    ///
2542    /// * On Unix, a path has a root if it begins with `/`.
2543    ///
2544    /// * On Windows, a path has a root if it:
2545    ///     * has no prefix and begins with a separator, e.g., `\windows`
2546    ///     * has a prefix followed by a separator, e.g., `c:\windows` but not `c:windows`
2547    ///     * has any non-disk prefix, e.g., `\\server\share`
2548    ///
2549    /// # Examples
2550    ///
2551    /// ```
2552    /// use std::path::Path;
2553    ///
2554    /// assert!(Path::new("/etc/passwd").has_root());
2555    /// ```
2556    #[stable(feature = "rust1", since = "1.0.0")]
2557    #[must_use]
2558    #[inline]
2559    pub fn has_root(&self) -> bool {
2560        self.components().has_root()
2561    }
2562
2563    /// Returns the `Path` without its final component, if there is one.
2564    ///
2565    /// This means it returns `Some("")` for relative paths with one component.
2566    ///
2567    /// Returns [`None`] if the path terminates in a root or prefix, or if it's
2568    /// the empty string.
2569    ///
2570    /// # Examples
2571    ///
2572    /// ```
2573    /// use std::path::Path;
2574    ///
2575    /// let path = Path::new("/foo/bar");
2576    /// let parent = path.parent().unwrap();
2577    /// assert_eq!(parent, Path::new("/foo"));
2578    ///
2579    /// let grand_parent = parent.parent().unwrap();
2580    /// assert_eq!(grand_parent, Path::new("/"));
2581    /// assert_eq!(grand_parent.parent(), None);
2582    ///
2583    /// let relative_path = Path::new("foo/bar");
2584    /// let parent = relative_path.parent();
2585    /// assert_eq!(parent, Some(Path::new("foo")));
2586    /// let grand_parent = parent.and_then(Path::parent);
2587    /// assert_eq!(grand_parent, Some(Path::new("")));
2588    /// let great_grand_parent = grand_parent.and_then(Path::parent);
2589    /// assert_eq!(great_grand_parent, None);
2590    /// ```
2591    #[stable(feature = "rust1", since = "1.0.0")]
2592    #[doc(alias = "dirname")]
2593    #[must_use]
2594    pub fn parent(&self) -> Option<&Path> {
2595        let mut comps = self.components();
2596        let comp = comps.next_back();
2597        comp.and_then(|p| match p {
2598            Component::Normal(_) | Component::CurDir | Component::ParentDir => {
2599                Some(comps.as_path())
2600            }
2601            _ => None,
2602        })
2603    }
2604
2605    /// Produces an iterator over `Path` and its ancestors.
2606    ///
2607    /// The iterator will yield the `Path` that is returned if the [`parent`] method is used zero
2608    /// or more times. If the [`parent`] method returns [`None`], the iterator will do likewise.
2609    /// The iterator will always yield at least one value, namely `Some(&self)`. Next it will yield
2610    /// `&self.parent()`, `&self.parent().and_then(Path::parent)` and so on.
2611    ///
2612    /// # Examples
2613    ///
2614    /// ```
2615    /// use std::path::Path;
2616    ///
2617    /// let mut ancestors = Path::new("/foo/bar").ancestors();
2618    /// assert_eq!(ancestors.next(), Some(Path::new("/foo/bar")));
2619    /// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
2620    /// assert_eq!(ancestors.next(), Some(Path::new("/")));
2621    /// assert_eq!(ancestors.next(), None);
2622    ///
2623    /// let mut ancestors = Path::new("../foo/bar").ancestors();
2624    /// assert_eq!(ancestors.next(), Some(Path::new("../foo/bar")));
2625    /// assert_eq!(ancestors.next(), Some(Path::new("../foo")));
2626    /// assert_eq!(ancestors.next(), Some(Path::new("..")));
2627    /// assert_eq!(ancestors.next(), Some(Path::new("")));
2628    /// assert_eq!(ancestors.next(), None);
2629    /// ```
2630    ///
2631    /// [`parent`]: Path::parent
2632    #[stable(feature = "path_ancestors", since = "1.28.0")]
2633    #[inline]
2634    pub fn ancestors(&self) -> Ancestors<'_> {
2635        Ancestors { next: Some(&self) }
2636    }
2637
2638    /// Returns the final component of the `Path`, if there is one.
2639    ///
2640    /// If the path is a normal file, this is the file name. If it's the path of a directory, this
2641    /// is the directory name.
2642    ///
2643    /// Returns [`None`] if the path terminates in `..`.
2644    ///
2645    /// # Examples
2646    ///
2647    /// ```
2648    /// use std::path::Path;
2649    /// use std::ffi::OsStr;
2650    ///
2651    /// assert_eq!(Some(OsStr::new("bin")), Path::new("/usr/bin/").file_name());
2652    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("tmp/foo.txt").file_name());
2653    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.").file_name());
2654    /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.//").file_name());
2655    /// assert_eq!(None, Path::new("foo.txt/..").file_name());
2656    /// assert_eq!(None, Path::new("/").file_name());
2657    /// ```
2658    #[stable(feature = "rust1", since = "1.0.0")]
2659    #[doc(alias = "basename")]
2660    #[must_use]
2661    pub fn file_name(&self) -> Option<&OsStr> {
2662        self.components().next_back().and_then(|p| match p {
2663            Component::Normal(p) => Some(p),
2664            _ => None,
2665        })
2666    }
2667
2668    /// Returns a path that, when joined onto `base`, yields `self`.
2669    ///
2670    /// # Errors
2671    ///
2672    /// If `base` is not a prefix of `self` (i.e., [`starts_with`]
2673    /// returns `false`), returns [`Err`].
2674    ///
2675    /// [`starts_with`]: Path::starts_with
2676    ///
2677    /// # Examples
2678    ///
2679    /// ```
2680    /// use std::path::{Path, PathBuf};
2681    ///
2682    /// let path = Path::new("/test/haha/foo.txt");
2683    ///
2684    /// assert_eq!(path.strip_prefix("/"), Ok(Path::new("test/haha/foo.txt")));
2685    /// assert_eq!(path.strip_prefix("/test"), Ok(Path::new("haha/foo.txt")));
2686    /// assert_eq!(path.strip_prefix("/test/"), Ok(Path::new("haha/foo.txt")));
2687    /// assert_eq!(path.strip_prefix("/test/haha/foo.txt"), Ok(Path::new("")));
2688    /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
2689    ///
2690    /// assert!(path.strip_prefix("test").is_err());
2691    /// assert!(path.strip_prefix("/te").is_err());
2692    /// assert!(path.strip_prefix("/haha").is_err());
2693    ///
2694    /// let prefix = PathBuf::from("/test/");
2695    /// assert_eq!(path.strip_prefix(prefix), Ok(Path::new("haha/foo.txt")));
2696    /// ```
2697    #[stable(since = "1.7.0", feature = "path_strip_prefix")]
2698    pub fn strip_prefix<P>(&self, base: P) -> Result<&Path, StripPrefixError>
2699    where
2700        P: AsRef<Path>,
2701    {
2702        self._strip_prefix(base.as_ref())
2703    }
2704
2705    fn _strip_prefix(&self, base: &Path) -> Result<&Path, StripPrefixError> {
2706        iter_after(self.components(), base.components())
2707            .map(|c| c.as_path())
2708            .ok_or(StripPrefixError(()))
2709    }
2710
2711    /// Determines whether `base` is a prefix of `self`.
2712    ///
2713    /// Only considers whole path components to match.
2714    ///
2715    /// # Examples
2716    ///
2717    /// ```
2718    /// use std::path::Path;
2719    ///
2720    /// let path = Path::new("/etc/passwd");
2721    ///
2722    /// assert!(path.starts_with("/etc"));
2723    /// assert!(path.starts_with("/etc/"));
2724    /// assert!(path.starts_with("/etc/passwd"));
2725    /// assert!(path.starts_with("/etc/passwd/")); // extra slash is okay
2726    /// assert!(path.starts_with("/etc/passwd///")); // multiple extra slashes are okay
2727    ///
2728    /// assert!(!path.starts_with("/e"));
2729    /// assert!(!path.starts_with("/etc/passwd.txt"));
2730    ///
2731    /// assert!(!Path::new("/etc/foo.rs").starts_with("/etc/foo"));
2732    /// ```
2733    #[stable(feature = "rust1", since = "1.0.0")]
2734    #[must_use]
2735    pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
2736        self._starts_with(base.as_ref())
2737    }
2738
2739    fn _starts_with(&self, base: &Path) -> bool {
2740        iter_after(self.components(), base.components()).is_some()
2741    }
2742
2743    /// Determines whether `child` is a suffix of `self`.
2744    ///
2745    /// Only considers whole path components to match.
2746    ///
2747    /// # Examples
2748    ///
2749    /// ```
2750    /// use std::path::Path;
2751    ///
2752    /// let path = Path::new("/etc/resolv.conf");
2753    ///
2754    /// assert!(path.ends_with("resolv.conf"));
2755    /// assert!(path.ends_with("etc/resolv.conf"));
2756    /// assert!(path.ends_with("/etc/resolv.conf"));
2757    ///
2758    /// assert!(!path.ends_with("/resolv.conf"));
2759    /// assert!(!path.ends_with("conf")); // use .extension() instead
2760    /// ```
2761    #[stable(feature = "rust1", since = "1.0.0")]
2762    #[must_use]
2763    pub fn ends_with<P: AsRef<Path>>(&self, child: P) -> bool {
2764        self._ends_with(child.as_ref())
2765    }
2766
2767    fn _ends_with(&self, child: &Path) -> bool {
2768        iter_after(self.components().rev(), child.components().rev()).is_some()
2769    }
2770
2771    /// Checks whether the `Path` is empty.
2772    ///
2773    /// # Examples
2774    ///
2775    /// ```
2776    /// #![feature(path_is_empty)]
2777    /// use std::path::Path;
2778    ///
2779    /// let path = Path::new("");
2780    /// assert!(path.is_empty());
2781    ///
2782    /// let path = Path::new("foo");
2783    /// assert!(!path.is_empty());
2784    ///
2785    /// let path = Path::new(".");
2786    /// assert!(!path.is_empty());
2787    /// ```
2788    #[unstable(feature = "path_is_empty", issue = "148494")]
2789    pub fn is_empty(&self) -> bool {
2790        self.as_os_str().is_empty()
2791    }
2792
2793    /// Extracts the stem (non-extension) portion of [`self.file_name`].
2794    ///
2795    /// [`self.file_name`]: Path::file_name
2796    ///
2797    /// The stem is:
2798    ///
2799    /// * [`None`], if there is no file name;
2800    /// * The entire file name if there is no embedded `.`;
2801    /// * The entire file name if the file name begins with `.` and has no other `.`s within;
2802    /// * Otherwise, the portion of the file name before the final `.`
2803    ///
2804    /// # Examples
2805    ///
2806    /// ```
2807    /// use std::path::Path;
2808    ///
2809    /// assert_eq!("foo", Path::new("foo.rs").file_stem().unwrap());
2810    /// assert_eq!("foo.tar", Path::new("foo.tar.gz").file_stem().unwrap());
2811    /// ```
2812    ///
2813    /// # See Also
2814    /// This method is similar to [`Path::file_prefix`], which extracts the portion of the file name
2815    /// before the *first* `.`
2816    ///
2817    /// [`Path::file_prefix`]: Path::file_prefix
2818    ///
2819    #[stable(feature = "rust1", since = "1.0.0")]
2820    #[must_use]
2821    pub fn file_stem(&self) -> Option<&OsStr> {
2822        self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.or(after))
2823    }
2824
2825    /// Extracts the prefix of [`self.file_name`].
2826    ///
2827    /// The prefix is:
2828    ///
2829    /// * [`None`], if there is no file name;
2830    /// * The entire file name if there is no embedded `.`;
2831    /// * The portion of the file name before the first non-beginning `.`;
2832    /// * The entire file name if the file name begins with `.` and has no other `.`s within;
2833    /// * The portion of the file name before the second `.` if the file name begins with `.`
2834    ///
2835    /// [`self.file_name`]: Path::file_name
2836    ///
2837    /// # Examples
2838    ///
2839    /// ```
2840    /// use std::path::Path;
2841    ///
2842    /// assert_eq!("foo", Path::new("foo.rs").file_prefix().unwrap());
2843    /// assert_eq!("foo", Path::new("foo.tar.gz").file_prefix().unwrap());
2844    /// assert_eq!(".config", Path::new(".config").file_prefix().unwrap());
2845    /// assert_eq!(".config", Path::new(".config.toml").file_prefix().unwrap());
2846    /// ```
2847    ///
2848    /// # See Also
2849    /// This method is similar to [`Path::file_stem`], which extracts the portion of the file name
2850    /// before the *last* `.`
2851    ///
2852    /// [`Path::file_stem`]: Path::file_stem
2853    ///
2854    #[stable(feature = "path_file_prefix", since = "1.91.0")]
2855    #[must_use]
2856    pub fn file_prefix(&self) -> Option<&OsStr> {
2857        self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before))
2858    }
2859
2860    /// Extracts the extension (without the leading dot) of [`self.file_name`], if possible.
2861    ///
2862    /// The extension is:
2863    ///
2864    /// * [`None`], if there is no file name;
2865    /// * [`None`], if there is no embedded `.`;
2866    /// * [`None`], if the file name begins with `.` and has no other `.`s within;
2867    /// * Otherwise, the portion of the file name after the final `.`
2868    ///
2869    /// [`self.file_name`]: Path::file_name
2870    ///
2871    /// # Examples
2872    ///
2873    /// ```
2874    /// use std::path::Path;
2875    ///
2876    /// assert_eq!("rs", Path::new("foo.rs").extension().unwrap());
2877    /// assert_eq!("gz", Path::new("foo.tar.gz").extension().unwrap());
2878    /// ```
2879    #[stable(feature = "rust1", since = "1.0.0")]
2880    #[must_use]
2881    pub fn extension(&self) -> Option<&OsStr> {
2882        self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.and(after))
2883    }
2884
2885    /// Checks whether the path ends in a trailing [separator](MAIN_SEPARATOR).
2886    ///
2887    /// This is generally done to ensure that a path is treated as a directory, not a file,
2888    /// although it does not actually guarantee that such a path is a directory on the underlying
2889    /// file system.
2890    ///
2891    /// Despite this behavior, two paths are still considered the same in Rust whether they have a
2892    /// trailing separator or not.
2893    ///
2894    /// # Examples
2895    ///
2896    /// ```
2897    /// #![feature(path_trailing_sep)]
2898    /// use std::path::Path;
2899    ///
2900    /// assert!(Path::new("dir/").has_trailing_sep());
2901    /// assert!(!Path::new("file.rs").has_trailing_sep());
2902    /// ```
2903    #[unstable(feature = "path_trailing_sep", issue = "142503")]
2904    #[must_use]
2905    #[inline]
2906    pub fn has_trailing_sep(&self) -> bool {
2907        self.as_os_str().as_encoded_bytes().last().copied().is_some_and(is_sep_byte)
2908    }
2909
2910    /// Ensures that a path has a trailing [separator](MAIN_SEPARATOR),
2911    /// allocating a [`PathBuf`] if necessary.
2912    ///
2913    /// The resulting path will return true for [`has_trailing_sep`](Self::has_trailing_sep).
2914    ///
2915    /// # Examples
2916    ///
2917    /// ```
2918    /// #![feature(path_trailing_sep)]
2919    /// use std::ffi::OsStr;
2920    /// use std::path::Path;
2921    ///
2922    /// assert_eq!(Path::new("dir//").with_trailing_sep().as_os_str(), OsStr::new("dir//"));
2923    /// assert_eq!(Path::new("dir/").with_trailing_sep().as_os_str(), OsStr::new("dir/"));
2924    /// assert!(!Path::new("dir").has_trailing_sep());
2925    /// assert!(Path::new("dir").with_trailing_sep().has_trailing_sep());
2926    /// ```
2927    #[unstable(feature = "path_trailing_sep", issue = "142503")]
2928    #[must_use]
2929    #[inline]
2930    pub fn with_trailing_sep(&self) -> Cow<'_, Path> {
2931        if self.has_trailing_sep() { Cow::Borrowed(self) } else { Cow::Owned(self.join("")) }
2932    }
2933
2934    /// Trims a trailing [separator](MAIN_SEPARATOR) from a path, if possible.
2935    ///
2936    /// The resulting path will return false for [`has_trailing_sep`](Self::has_trailing_sep) for
2937    /// most paths.
2938    ///
2939    /// Some paths, like `/`, cannot be trimmed in this way.
2940    ///
2941    /// # Examples
2942    ///
2943    /// ```
2944    /// #![feature(path_trailing_sep)]
2945    /// use std::ffi::OsStr;
2946    /// use std::path::Path;
2947    ///
2948    /// assert_eq!(Path::new("dir//").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
2949    /// assert_eq!(Path::new("dir/").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
2950    /// assert_eq!(Path::new("dir").trim_trailing_sep().as_os_str(), OsStr::new("dir"));
2951    /// assert_eq!(Path::new("/").trim_trailing_sep().as_os_str(), OsStr::new("/"));
2952    /// assert_eq!(Path::new("//").trim_trailing_sep().as_os_str(), OsStr::new("//"));
2953    /// ```
2954    #[unstable(feature = "path_trailing_sep", issue = "142503")]
2955    #[must_use]
2956    #[inline]
2957    pub fn trim_trailing_sep(&self) -> &Path {
2958        if self.has_trailing_sep() && (!self.has_root() || self.parent().is_some()) {
2959            let mut bytes = self.inner.as_encoded_bytes();
2960            while let Some((last, init)) = bytes.split_last()
2961                && is_sep_byte(*last)
2962            {
2963                bytes = init;
2964            }
2965
2966            // SAFETY: Trimming trailing ASCII bytes will retain the validity of the string.
2967            Path::new(unsafe { OsStr::from_encoded_bytes_unchecked(bytes) })
2968        } else {
2969            self
2970        }
2971    }
2972
2973    /// Creates an owned [`PathBuf`] with `path` adjoined to `self`.
2974    ///
2975    /// If `path` is absolute, it replaces the current path.
2976    ///
2977    /// See [`PathBuf::push`] for more details on what it means to adjoin a path.
2978    ///
2979    /// # Examples
2980    ///
2981    /// ```
2982    /// use std::path::{Path, PathBuf};
2983    ///
2984    /// assert_eq!(Path::new("/etc").join("passwd"), PathBuf::from("/etc/passwd"));
2985    /// assert_eq!(Path::new("/etc").join("/bin/sh"), PathBuf::from("/bin/sh"));
2986    /// ```
2987    #[stable(feature = "rust1", since = "1.0.0")]
2988    #[must_use]
2989    pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
2990        self._join(path.as_ref())
2991    }
2992
2993    fn _join(&self, path: &Path) -> PathBuf {
2994        let mut buf = self.to_path_buf();
2995        buf.push(path);
2996        buf
2997    }
2998
2999    /// Creates an owned [`PathBuf`] like `self` but with the given file name.
3000    ///
3001    /// See [`PathBuf::set_file_name`] for more details.
3002    ///
3003    /// # Examples
3004    ///
3005    /// ```
3006    /// use std::path::{Path, PathBuf};
3007    ///
3008    /// let path = Path::new("/tmp/foo.png");
3009    /// assert_eq!(path.with_file_name("bar"), PathBuf::from("/tmp/bar"));
3010    /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt"));
3011    ///
3012    /// let path = Path::new("/tmp");
3013    /// assert_eq!(path.with_file_name("var"), PathBuf::from("/var"));
3014    /// ```
3015    #[stable(feature = "rust1", since = "1.0.0")]
3016    #[must_use]
3017    pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
3018        self._with_file_name(file_name.as_ref())
3019    }
3020
3021    fn _with_file_name(&self, file_name: &OsStr) -> PathBuf {
3022        let mut buf = self.to_path_buf();
3023        buf.set_file_name(file_name);
3024        buf
3025    }
3026
3027    /// Creates an owned [`PathBuf`] like `self` but with the given extension.
3028    ///
3029    /// See [`PathBuf::set_extension`] for more details.
3030    ///
3031    /// # Examples
3032    ///
3033    /// ```
3034    /// use std::path::Path;
3035    ///
3036    /// let path = Path::new("foo.rs");
3037    /// assert_eq!(path.with_extension("txt"), Path::new("foo.txt"));
3038    /// assert_eq!(path.with_extension(""), Path::new("foo"));
3039    /// ```
3040    ///
3041    /// Handling multiple extensions:
3042    ///
3043    /// ```
3044    /// use std::path::Path;
3045    ///
3046    /// let path = Path::new("foo.tar.gz");
3047    /// assert_eq!(path.with_extension("xz"), Path::new("foo.tar.xz"));
3048    /// assert_eq!(path.with_extension("").with_extension("txt"), Path::new("foo.txt"));
3049    /// ```
3050    ///
3051    /// Adding an extension where one did not exist:
3052    ///
3053    /// ```
3054    /// use std::path::Path;
3055    ///
3056    /// let path = Path::new("foo");
3057    /// assert_eq!(path.with_extension("rs"), Path::new("foo.rs"));
3058    /// ```
3059    #[stable(feature = "rust1", since = "1.0.0")]
3060    pub fn with_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
3061        self._with_extension(extension.as_ref())
3062    }
3063
3064    fn _with_extension(&self, extension: &OsStr) -> PathBuf {
3065        let self_len = self.as_os_str().len();
3066        let self_bytes = self.as_os_str().as_encoded_bytes();
3067
3068        let (new_capacity, slice_to_copy) = match self.extension() {
3069            None => {
3070                // Enough capacity for the extension and the dot
3071                let capacity = self_len + extension.len() + 1;
3072                let whole_path = self_bytes;
3073                (capacity, whole_path)
3074            }
3075            Some(previous_extension) => {
3076                let capacity = self_len + extension.len() - previous_extension.len();
3077                let path_till_dot = &self_bytes[..self_len - previous_extension.len()];
3078                (capacity, path_till_dot)
3079            }
3080        };
3081
3082        let mut new_path = PathBuf::with_capacity(new_capacity);
3083        // SAFETY: The path is empty, so cannot have surrogate halves.
3084        unsafe { new_path.inner.extend_from_slice_unchecked(slice_to_copy) };
3085        new_path.set_extension(extension);
3086        new_path
3087    }
3088
3089    /// Creates an owned [`PathBuf`] like `self` but with the extension added.
3090    ///
3091    /// See [`PathBuf::add_extension`] for more details.
3092    ///
3093    /// # Examples
3094    ///
3095    /// ```
3096    /// use std::path::{Path, PathBuf};
3097    ///
3098    /// let path = Path::new("foo.rs");
3099    /// assert_eq!(path.with_added_extension("txt"), PathBuf::from("foo.rs.txt"));
3100    ///
3101    /// let path = Path::new("foo.tar.gz");
3102    /// assert_eq!(path.with_added_extension(""), PathBuf::from("foo.tar.gz"));
3103    /// assert_eq!(path.with_added_extension("xz"), PathBuf::from("foo.tar.gz.xz"));
3104    /// assert_eq!(path.with_added_extension("").with_added_extension("txt"), PathBuf::from("foo.tar.gz.txt"));
3105    /// ```
3106    #[stable(feature = "path_add_extension", since = "1.91.0")]
3107    pub fn with_added_extension<S: AsRef<OsStr>>(&self, extension: S) -> PathBuf {
3108        let mut new_path = self.to_path_buf();
3109        new_path.add_extension(extension);
3110        new_path
3111    }
3112
3113    /// Produces an iterator over the [`Component`]s of the path.
3114    ///
3115    /// When parsing the path, there is a small amount of normalization:
3116    ///
3117    /// * Repeated separators are ignored, so `a/b` and `a//b` both have
3118    ///   `a` and `b` as components.
3119    ///
3120    /// * Occurrences of `.` are normalized away, except if they are at the
3121    ///   beginning of the path. For example, `a/./b`, `a/b/`, `a/b/.` and
3122    ///   `a/b` all have `a` and `b` as components, but `./a/b` starts with
3123    ///   an additional [`CurDir`] component.
3124    ///
3125    /// * Trailing separators are normalized away, so `/a/b` and `/a/b/` are equivalent.
3126    ///
3127    /// Note that no other normalization takes place; in particular, `a/c`
3128    /// and `a/b/../c` are distinct, to account for the possibility that `b`
3129    /// is a symbolic link (so its parent isn't `a`).
3130    ///
3131    /// # Examples
3132    ///
3133    /// ```
3134    /// use std::path::{Path, Component};
3135    /// use std::ffi::OsStr;
3136    ///
3137    /// let mut components = Path::new("/tmp/foo.txt").components();
3138    ///
3139    /// assert_eq!(components.next(), Some(Component::RootDir));
3140    /// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("tmp"))));
3141    /// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("foo.txt"))));
3142    /// assert_eq!(components.next(), None)
3143    /// ```
3144    ///
3145    /// [`CurDir`]: Component::CurDir
3146    #[stable(feature = "rust1", since = "1.0.0")]
3147    pub fn components(&self) -> Components<'_> {
3148        let prefix = parse_prefix(self.as_os_str());
3149        Components {
3150            path: self.as_u8_slice(),
3151            prefix,
3152            has_physical_root: has_physical_root(self.as_u8_slice(), prefix),
3153            // use a platform-specific initial state to avoid one turn of
3154            // the state-machine when the platform doesn't have a Prefix.
3155            front: const { if HAS_PREFIXES { State::Prefix } else { State::StartDir } },
3156            back: State::Body,
3157        }
3158    }
3159
3160    /// Produces an iterator over the path's components viewed as [`OsStr`]
3161    /// slices.
3162    ///
3163    /// For more information about the particulars of how the path is separated
3164    /// into components, see [`components`].
3165    ///
3166    /// [`components`]: Path::components
3167    ///
3168    /// # Examples
3169    ///
3170    /// ```
3171    /// use std::path::{self, Path};
3172    /// use std::ffi::OsStr;
3173    ///
3174    /// let mut it = Path::new("/tmp/foo.txt").iter();
3175    /// assert_eq!(it.next(), Some(OsStr::new(&path::MAIN_SEPARATOR.to_string())));
3176    /// assert_eq!(it.next(), Some(OsStr::new("tmp")));
3177    /// assert_eq!(it.next(), Some(OsStr::new("foo.txt")));
3178    /// assert_eq!(it.next(), None)
3179    /// ```
3180    #[stable(feature = "rust1", since = "1.0.0")]
3181    #[inline]
3182    pub fn iter(&self) -> Iter<'_> {
3183        Iter { inner: self.components() }
3184    }
3185
3186    /// Returns an object that implements [`Display`] for safely printing paths
3187    /// that may contain non-Unicode data. This may perform lossy conversion,
3188    /// depending on the platform.  If you would like an implementation which
3189    /// escapes the path please use [`Debug`] instead.
3190    ///
3191    /// [`Display`]: fmt::Display
3192    /// [`Debug`]: fmt::Debug
3193    ///
3194    /// # Examples
3195    ///
3196    /// ```
3197    /// use std::path::Path;
3198    ///
3199    /// let path = Path::new("/tmp/foo.rs");
3200    ///
3201    /// println!("{}", path.display());
3202    /// ```
3203    #[stable(feature = "rust1", since = "1.0.0")]
3204    #[must_use = "this does not display the path, \
3205                  it returns an object that can be displayed"]
3206    #[inline]
3207    pub fn display(&self) -> Display<'_> {
3208        Display { inner: self.inner.display() }
3209    }
3210
3211    /// Queries the file system to get information about a file, directory, etc.
3212    ///
3213    /// This function will traverse symbolic links to query information about the
3214    /// destination file.
3215    ///
3216    /// This is an alias to [`fs::metadata`].
3217    ///
3218    /// # Examples
3219    ///
3220    /// ```no_run
3221    /// use std::path::Path;
3222    ///
3223    /// let path = Path::new("/Minas/tirith");
3224    /// let metadata = path.metadata().expect("metadata call failed");
3225    /// println!("{:?}", metadata.file_type());
3226    /// ```
3227    #[stable(feature = "path_ext", since = "1.5.0")]
3228    #[inline]
3229    pub fn metadata(&self) -> io::Result<fs::Metadata> {
3230        fs::metadata(self)
3231    }
3232
3233    /// Queries the metadata about a file without following symlinks.
3234    ///
3235    /// This is an alias to [`fs::symlink_metadata`].
3236    ///
3237    /// # Examples
3238    ///
3239    /// ```no_run
3240    /// use std::path::Path;
3241    ///
3242    /// let path = Path::new("/Minas/tirith");
3243    /// let metadata = path.symlink_metadata().expect("symlink_metadata call failed");
3244    /// println!("{:?}", metadata.file_type());
3245    /// ```
3246    #[stable(feature = "path_ext", since = "1.5.0")]
3247    #[inline]
3248    pub fn symlink_metadata(&self) -> io::Result<fs::Metadata> {
3249        fs::symlink_metadata(self)
3250    }
3251
3252    /// Returns the canonical, absolute form of the path with all intermediate
3253    /// components normalized and symbolic links resolved.
3254    ///
3255    /// This is an alias to [`fs::canonicalize`].
3256    ///
3257    /// # Errors
3258    ///
3259    /// This method will return an error in the following situations, but is not
3260    /// limited to just these cases:
3261    ///
3262    /// * `path` does not exist.
3263    /// * A non-final component in path is not a directory.
3264    ///
3265    /// # Examples
3266    ///
3267    /// ```no_run
3268    /// use std::path::{Path, PathBuf};
3269    ///
3270    /// let path = Path::new("/foo/test/../test/bar.rs");
3271    /// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs"));
3272    /// ```
3273    #[stable(feature = "path_ext", since = "1.5.0")]
3274    #[inline]
3275    pub fn canonicalize(&self) -> io::Result<PathBuf> {
3276        fs::canonicalize(self)
3277    }
3278
3279    /// Normalize a path, including `..` without traversing the filesystem.
3280    ///
3281    /// Returns an error if normalization would leave leading `..` components.
3282    ///
3283    /// <div class="warning">
3284    ///
3285    /// This function always resolves `..` to the "lexical" parent.
3286    /// That is "a/b/../c" will always resolve to `a/c` which can change the meaning of the path.
3287    /// In particular, `a/c` and `a/b/../c` are distinct on many systems because `b` may be a symbolic link, so its parent isn't `a`.
3288    ///
3289    /// </div>
3290    ///
3291    /// [`path::absolute`](absolute) is an alternative that preserves `..`.
3292    /// Or [`Path::canonicalize`] can be used to resolve any `..` by querying the filesystem.
3293    #[unstable(feature = "normalize_lexically", issue = "134694")]
3294    pub fn normalize_lexically(&self) -> Result<PathBuf, NormalizeError> {
3295        let mut lexical = PathBuf::new();
3296        let mut iter = self.components().peekable();
3297
3298        // Find the root, if any, and add it to the lexical path.
3299        // Here we treat the Windows path "C:\" as a single "root" even though
3300        // `components` splits it into two: (Prefix, RootDir).
3301        let root = match iter.peek() {
3302            Some(Component::ParentDir) => return Err(NormalizeError),
3303            Some(p @ Component::RootDir) | Some(p @ Component::CurDir) => {
3304                lexical.push(p);
3305                iter.next();
3306                lexical.as_os_str().len()
3307            }
3308            Some(Component::Prefix(prefix)) => {
3309                lexical.push(prefix.as_os_str());
3310                iter.next();
3311                if let Some(p @ Component::RootDir) = iter.peek() {
3312                    lexical.push(p);
3313                    iter.next();
3314                }
3315                lexical.as_os_str().len()
3316            }
3317            None => return Ok(PathBuf::new()),
3318            Some(Component::Normal(_)) => 0,
3319        };
3320
3321        for component in iter {
3322            match component {
3323                Component::RootDir => unreachable!(),
3324                Component::Prefix(_) => return Err(NormalizeError),
3325                Component::CurDir => continue,
3326                Component::ParentDir => {
3327                    // It's an error if ParentDir causes us to go above the "root".
3328                    if lexical.as_os_str().len() == root {
3329                        return Err(NormalizeError);
3330                    } else {
3331                        lexical.pop();
3332                    }
3333                }
3334                Component::Normal(path) => lexical.push(path),
3335            }
3336        }
3337        Ok(lexical)
3338    }
3339
3340    /// Reads a symbolic link, returning the file that the link points to.
3341    ///
3342    /// This is an alias to [`fs::read_link`].
3343    ///
3344    /// # Examples
3345    ///
3346    /// ```no_run
3347    /// use std::path::Path;
3348    ///
3349    /// let path = Path::new("/laputa/sky_castle.rs");
3350    /// let path_link = path.read_link().expect("read_link call failed");
3351    /// ```
3352    #[stable(feature = "path_ext", since = "1.5.0")]
3353    #[inline]
3354    pub fn read_link(&self) -> io::Result<PathBuf> {
3355        fs::read_link(self)
3356    }
3357
3358    /// Returns an iterator over the entries within a directory.
3359    ///
3360    /// The iterator will yield instances of <code>[io::Result]<[fs::DirEntry]></code>. New
3361    /// errors may be encountered after an iterator is initially constructed.
3362    ///
3363    /// This is an alias to [`fs::read_dir`].
3364    ///
3365    /// # Examples
3366    ///
3367    /// ```no_run
3368    /// use std::path::Path;
3369    ///
3370    /// let path = Path::new("/laputa");
3371    /// for entry in path.read_dir().expect("read_dir call failed") {
3372    ///     if let Ok(entry) = entry {
3373    ///         println!("{:?}", entry.path());
3374    ///     }
3375    /// }
3376    /// ```
3377    #[stable(feature = "path_ext", since = "1.5.0")]
3378    #[inline]
3379    pub fn read_dir(&self) -> io::Result<fs::ReadDir> {
3380        fs::read_dir(self)
3381    }
3382
3383    /// Returns `true` if the path points at an existing entity.
3384    ///
3385    /// Warning: this method may be error-prone, consider using [`try_exists()`] instead!
3386    /// It also has a risk of introducing time-of-check to time-of-use ([TOCTOU]) bugs.
3387    ///
3388    /// This function will traverse symbolic links to query information about the
3389    /// destination file.
3390    ///
3391    /// If you cannot access the metadata of the file, e.g. because of a
3392    /// permission error or broken symbolic links, this will return `false`.
3393    ///
3394    /// # Examples
3395    ///
3396    /// ```no_run
3397    /// use std::path::Path;
3398    /// assert!(!Path::new("does_not_exist.txt").exists());
3399    /// ```
3400    ///
3401    /// # See Also
3402    ///
3403    /// This is a convenience function that coerces errors to false. If you want to
3404    /// check errors, call [`Path::try_exists`].
3405    ///
3406    /// [`try_exists()`]: Self::try_exists
3407    /// [TOCTOU]: fs#time-of-check-to-time-of-use-toctou
3408    #[stable(feature = "path_ext", since = "1.5.0")]
3409    #[must_use]
3410    #[inline]
3411    pub fn exists(&self) -> bool {
3412        fs::metadata(self).is_ok()
3413    }
3414
3415    /// Returns `Ok(true)` if the path points at an existing entity.
3416    ///
3417    /// This function will traverse symbolic links to query information about the
3418    /// destination file. In case of broken symbolic links this will return `Ok(false)`.
3419    ///
3420    /// [`Path::exists()`] only checks whether or not a path was both found and readable. By
3421    /// contrast, `try_exists` will return `Ok(true)` or `Ok(false)`, respectively, if the path
3422    /// was _verified_ to exist or not exist. If its existence can neither be confirmed nor
3423    /// denied, it will propagate an `Err(_)` instead. This can be the case if e.g. listing
3424    /// permission is denied on one of the parent directories.
3425    ///
3426    /// Note that while this avoids some pitfalls of the `exists()` method, it still can not
3427    /// prevent time-of-check to time-of-use ([TOCTOU]) bugs. You should only use it in scenarios
3428    /// where those bugs are not an issue.
3429    ///
3430    /// This is an alias for [`std::fs::exists`](crate::fs::exists).
3431    ///
3432    /// # Examples
3433    ///
3434    /// ```no_run
3435    /// use std::path::Path;
3436    /// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
3437    /// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
3438    /// ```
3439    ///
3440    /// [TOCTOU]: fs#time-of-check-to-time-of-use-toctou
3441    /// [`exists()`]: Self::exists
3442    #[stable(feature = "path_try_exists", since = "1.63.0")]
3443    #[inline]
3444    pub fn try_exists(&self) -> io::Result<bool> {
3445        fs::exists(self)
3446    }
3447
3448    /// Returns `true` if the path exists on disk and is pointing at a regular file.
3449    ///
3450    /// This function will traverse symbolic links to query information about the
3451    /// destination file.
3452    ///
3453    /// If you cannot access the metadata of the file, e.g. because of a
3454    /// permission error or broken symbolic links, this will return `false`.
3455    ///
3456    /// # Examples
3457    ///
3458    /// ```no_run
3459    /// use std::path::Path;
3460    /// assert_eq!(Path::new("./is_a_directory/").is_file(), false);
3461    /// assert_eq!(Path::new("a_file.txt").is_file(), true);
3462    /// ```
3463    ///
3464    /// # See Also
3465    ///
3466    /// This is a convenience function that coerces errors to false. If you want to
3467    /// check errors, call [`fs::metadata`] and handle its [`Result`]. Then call
3468    /// [`fs::Metadata::is_file`] if it was [`Ok`].
3469    ///
3470    /// When the goal is simply to read from (or write to) the source, the most
3471    /// reliable way to test the source can be read (or written to) is to open
3472    /// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
3473    /// a Unix-like system for example. See [`fs::File::open`] or
3474    /// [`fs::OpenOptions::open`] for more information.
3475    #[stable(feature = "path_ext", since = "1.5.0")]
3476    #[must_use]
3477    pub fn is_file(&self) -> bool {
3478        fs::metadata(self).map(|m| m.is_file()).unwrap_or(false)
3479    }
3480
3481    /// Returns `true` if the path exists on disk and is pointing at a directory.
3482    ///
3483    /// This function will traverse symbolic links to query information about the
3484    /// destination file.
3485    ///
3486    /// If you cannot access the metadata of the file, e.g. because of a
3487    /// permission error or broken symbolic links, this will return `false`.
3488    ///
3489    /// # Examples
3490    ///
3491    /// ```no_run
3492    /// use std::path::Path;
3493    /// assert_eq!(Path::new("./is_a_directory/").is_dir(), true);
3494    /// assert_eq!(Path::new("a_file.txt").is_dir(), false);
3495    /// ```
3496    ///
3497    /// # See Also
3498    ///
3499    /// This is a convenience function that coerces errors to false. If you want to
3500    /// check errors, call [`fs::metadata`] and handle its [`Result`]. Then call
3501    /// [`fs::Metadata::is_dir`] if it was [`Ok`].
3502    #[stable(feature = "path_ext", since = "1.5.0")]
3503    #[must_use]
3504    pub fn is_dir(&self) -> bool {
3505        fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
3506    }
3507
3508    /// Returns `true` if the path exists on disk and is pointing at a symbolic link.
3509    ///
3510    /// This function will not traverse symbolic links.
3511    /// In case of a broken symbolic link this will also return true.
3512    ///
3513    /// If you cannot access the directory containing the file, e.g., because of a
3514    /// permission error, this will return false.
3515    ///
3516    /// # Examples
3517    ///
3518    /// ```rust,no_run
3519    /// # #[cfg(unix)] {
3520    /// use std::path::Path;
3521    /// use std::os::unix::fs::symlink;
3522    ///
3523    /// let link_path = Path::new("link");
3524    /// symlink("/origin_does_not_exist/", link_path).unwrap();
3525    /// assert_eq!(link_path.is_symlink(), true);
3526    /// assert_eq!(link_path.exists(), false);
3527    /// # }
3528    /// ```
3529    ///
3530    /// # See Also
3531    ///
3532    /// This is a convenience function that coerces errors to false. If you want to
3533    /// check errors, call [`fs::symlink_metadata`] and handle its [`Result`]. Then call
3534    /// [`fs::Metadata::is_symlink`] if it was [`Ok`].
3535    #[must_use]
3536    #[stable(feature = "is_symlink", since = "1.58.0")]
3537    pub fn is_symlink(&self) -> bool {
3538        fs::symlink_metadata(self).map(|m| m.is_symlink()).unwrap_or(false)
3539    }
3540
3541    /// Converts a [`Box<Path>`](Box) into a [`PathBuf`] without copying or
3542    /// allocating.
3543    #[stable(feature = "into_boxed_path", since = "1.20.0")]
3544    #[must_use = "`self` will be dropped if the result is not used"]
3545    pub fn into_path_buf(self: Box<Self>) -> PathBuf {
3546        let rw = Box::into_raw(self) as *mut OsStr;
3547        let inner = unsafe { Box::from_raw(rw) };
3548        PathBuf { inner: OsString::from(inner) }
3549    }
3550}
3551
3552#[unstable(feature = "clone_to_uninit", issue = "126799")]
3553unsafe impl CloneToUninit for Path {
3554    #[inline]
3555    #[cfg_attr(debug_assertions, track_caller)]
3556    unsafe fn clone_to_uninit(&self, dst: *mut u8) {
3557        // SAFETY: Path is just a transparent wrapper around OsStr
3558        unsafe { self.inner.clone_to_uninit(dst) }
3559    }
3560}
3561
3562#[stable(feature = "rust1", since = "1.0.0")]
3563#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
3564impl const AsRef<OsStr> for Path {
3565    #[inline]
3566    fn as_ref(&self) -> &OsStr {
3567        &self.inner
3568    }
3569}
3570
3571#[stable(feature = "rust1", since = "1.0.0")]
3572impl fmt::Debug for Path {
3573    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
3574        fmt::Debug::fmt(&self.inner, formatter)
3575    }
3576}
3577
3578/// Helper struct for safely printing paths with [`format!`] and `{}`.
3579///
3580/// A [`Path`] might contain non-Unicode data. This `struct` implements the
3581/// [`Display`] trait in a way that mitigates that. It is created by the
3582/// [`display`](Path::display) method on [`Path`]. This may perform lossy
3583/// conversion, depending on the platform. If you would like an implementation
3584/// which escapes the path please use [`Debug`] instead.
3585///
3586/// # Examples
3587///
3588/// ```
3589/// use std::path::Path;
3590///
3591/// let path = Path::new("/tmp/foo.rs");
3592///
3593/// println!("{}", path.display());
3594/// ```
3595///
3596/// [`Display`]: fmt::Display
3597/// [`format!`]: crate::format
3598#[stable(feature = "rust1", since = "1.0.0")]
3599pub struct Display<'a> {
3600    inner: os_str::Display<'a>,
3601}
3602
3603#[stable(feature = "rust1", since = "1.0.0")]
3604impl fmt::Debug for Display<'_> {
3605    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3606        fmt::Debug::fmt(&self.inner, f)
3607    }
3608}
3609
3610#[stable(feature = "rust1", since = "1.0.0")]
3611impl fmt::Display for Display<'_> {
3612    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3613        fmt::Display::fmt(&self.inner, f)
3614    }
3615}
3616
3617#[stable(feature = "rust1", since = "1.0.0")]
3618impl PartialEq for Path {
3619    #[inline]
3620    fn eq(&self, other: &Path) -> bool {
3621        self.components() == other.components()
3622    }
3623}
3624
3625#[stable(feature = "eq_str_for_path", since = "1.91.0")]
3626impl cmp::PartialEq<str> for Path {
3627    #[inline]
3628    fn eq(&self, other: &str) -> bool {
3629        let other: &OsStr = other.as_ref();
3630        self == other
3631    }
3632}
3633
3634#[stable(feature = "eq_str_for_path", since = "1.91.0")]
3635impl cmp::PartialEq<Path> for str {
3636    #[inline]
3637    fn eq(&self, other: &Path) -> bool {
3638        other == self
3639    }
3640}
3641
3642#[stable(feature = "eq_str_for_path", since = "1.91.0")]
3643impl cmp::PartialEq<String> for Path {
3644    #[inline]
3645    fn eq(&self, other: &String) -> bool {
3646        self == other.as_str()
3647    }
3648}
3649
3650#[stable(feature = "eq_str_for_path", since = "1.91.0")]
3651impl cmp::PartialEq<Path> for String {
3652    #[inline]
3653    fn eq(&self, other: &Path) -> bool {
3654        self.as_str() == other
3655    }
3656}
3657
3658#[stable(feature = "rust1", since = "1.0.0")]
3659impl Hash for Path {
3660    fn hash<H: Hasher>(&self, h: &mut H) {
3661        let bytes = self.as_u8_slice();
3662        let (prefix_len, verbatim) = match parse_prefix(&self.inner) {
3663            Some(prefix) => {
3664                prefix.hash(h);
3665                (prefix.len(), prefix.is_verbatim())
3666            }
3667            None => (0, false),
3668        };
3669        let bytes = &bytes[prefix_len..];
3670
3671        let mut component_start = 0;
3672        // track some extra state to avoid prefix collisions.
3673        // ["foo", "bar"] and ["foobar"], will have the same payload bytes
3674        // but result in different chunk_bits
3675        let mut chunk_bits: usize = 0;
3676
3677        for i in 0..bytes.len() {
3678            let is_sep = if verbatim { is_verbatim_sep(bytes[i]) } else { is_sep_byte(bytes[i]) };
3679            if is_sep {
3680                if i > component_start {
3681                    let to_hash = &bytes[component_start..i];
3682                    chunk_bits = chunk_bits.wrapping_add(to_hash.len());
3683                    chunk_bits = chunk_bits.rotate_right(2);
3684                    h.write(to_hash);
3685                }
3686
3687                // skip over separator and optionally a following CurDir item
3688                // since components() would normalize these away.
3689                component_start = i + 1;
3690
3691                let tail = &bytes[component_start..];
3692
3693                if !verbatim {
3694                    component_start += match tail {
3695                        [b'.'] => 1,
3696                        [b'.', sep, ..] if is_sep_byte(*sep) => 1,
3697                        _ => 0,
3698                    };
3699                }
3700            }
3701        }
3702
3703        if component_start < bytes.len() {
3704            let to_hash = &bytes[component_start..];
3705            chunk_bits = chunk_bits.wrapping_add(to_hash.len());
3706            chunk_bits = chunk_bits.rotate_right(2);
3707            h.write(to_hash);
3708        }
3709
3710        h.write_usize(chunk_bits);
3711    }
3712}
3713
3714#[stable(feature = "rust1", since = "1.0.0")]
3715impl Eq for Path {}
3716
3717#[stable(feature = "rust1", since = "1.0.0")]
3718impl PartialOrd for Path {
3719    #[inline]
3720    fn partial_cmp(&self, other: &Path) -> Option<cmp::Ordering> {
3721        Some(compare_components(self.components(), other.components()))
3722    }
3723}
3724
3725#[stable(feature = "rust1", since = "1.0.0")]
3726impl Ord for Path {
3727    #[inline]
3728    fn cmp(&self, other: &Path) -> cmp::Ordering {
3729        compare_components(self.components(), other.components())
3730    }
3731}
3732
3733#[stable(feature = "rust1", since = "1.0.0")]
3734#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
3735impl const AsRef<Path> for Path {
3736    #[inline]
3737    fn as_ref(&self) -> &Path {
3738        self
3739    }
3740}
3741
3742#[stable(feature = "rust1", since = "1.0.0")]
3743#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
3744impl const AsRef<Path> for OsStr {
3745    #[inline]
3746    fn as_ref(&self) -> &Path {
3747        Path::new(self)
3748    }
3749}
3750
3751#[stable(feature = "cow_os_str_as_ref_path", since = "1.8.0")]
3752impl AsRef<Path> for Cow<'_, OsStr> {
3753    #[inline]
3754    fn as_ref(&self) -> &Path {
3755        Path::new(self)
3756    }
3757}
3758
3759#[stable(feature = "rust1", since = "1.0.0")]
3760impl AsRef<Path> for OsString {
3761    #[inline]
3762    fn as_ref(&self) -> &Path {
3763        Path::new(self)
3764    }
3765}
3766
3767#[stable(feature = "rust1", since = "1.0.0")]
3768impl AsRef<Path> for str {
3769    #[inline]
3770    fn as_ref(&self) -> &Path {
3771        Path::new(self)
3772    }
3773}
3774
3775#[stable(feature = "rust1", since = "1.0.0")]
3776impl AsRef<Path> for String {
3777    #[inline]
3778    fn as_ref(&self) -> &Path {
3779        Path::new(self)
3780    }
3781}
3782
3783#[stable(feature = "rust1", since = "1.0.0")]
3784impl AsRef<Path> for PathBuf {
3785    #[inline]
3786    fn as_ref(&self) -> &Path {
3787        self
3788    }
3789}
3790
3791#[stable(feature = "path_into_iter", since = "1.6.0")]
3792impl<'a> IntoIterator for &'a PathBuf {
3793    type Item = &'a OsStr;
3794    type IntoIter = Iter<'a>;
3795    #[inline]
3796    fn into_iter(self) -> Iter<'a> {
3797        self.iter()
3798    }
3799}
3800
3801#[stable(feature = "path_into_iter", since = "1.6.0")]
3802impl<'a> IntoIterator for &'a Path {
3803    type Item = &'a OsStr;
3804    type IntoIter = Iter<'a>;
3805    #[inline]
3806    fn into_iter(self) -> Iter<'a> {
3807        self.iter()
3808    }
3809}
3810
3811macro_rules! impl_cmp {
3812    (<$($life:lifetime),*> $lhs:ty, $rhs: ty) => {
3813        #[stable(feature = "partialeq_path", since = "1.6.0")]
3814        impl<$($life),*> PartialEq<$rhs> for $lhs {
3815            #[inline]
3816            fn eq(&self, other: &$rhs) -> bool {
3817                <Path as PartialEq>::eq(self, other)
3818            }
3819        }
3820
3821        #[stable(feature = "partialeq_path", since = "1.6.0")]
3822        impl<$($life),*> PartialEq<$lhs> for $rhs {
3823            #[inline]
3824            fn eq(&self, other: &$lhs) -> bool {
3825                <Path as PartialEq>::eq(self, other)
3826            }
3827        }
3828
3829        #[stable(feature = "cmp_path", since = "1.8.0")]
3830        impl<$($life),*> PartialOrd<$rhs> for $lhs {
3831            #[inline]
3832            fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
3833                <Path as PartialOrd>::partial_cmp(self, other)
3834            }
3835        }
3836
3837        #[stable(feature = "cmp_path", since = "1.8.0")]
3838        impl<$($life),*> PartialOrd<$lhs> for $rhs {
3839            #[inline]
3840            fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
3841                <Path as PartialOrd>::partial_cmp(self, other)
3842            }
3843        }
3844    };
3845}
3846
3847impl_cmp!(<> PathBuf, Path);
3848impl_cmp!(<'a> PathBuf, &'a Path);
3849impl_cmp!(<'a> Cow<'a, Path>, Path);
3850impl_cmp!(<'a, 'b> Cow<'a, Path>, &'b Path);
3851impl_cmp!(<'a> Cow<'a, Path>, PathBuf);
3852
3853macro_rules! impl_cmp_os_str {
3854    (<$($life:lifetime),*> $lhs:ty, $rhs: ty) => {
3855        #[stable(feature = "cmp_path", since = "1.8.0")]
3856        impl<$($life),*> PartialEq<$rhs> for $lhs {
3857            #[inline]
3858            fn eq(&self, other: &$rhs) -> bool {
3859                <Path as PartialEq>::eq(self, other.as_ref())
3860            }
3861        }
3862
3863        #[stable(feature = "cmp_path", since = "1.8.0")]
3864        impl<$($life),*> PartialEq<$lhs> for $rhs {
3865            #[inline]
3866            fn eq(&self, other: &$lhs) -> bool {
3867                <Path as PartialEq>::eq(self.as_ref(), other)
3868            }
3869        }
3870
3871        #[stable(feature = "cmp_path", since = "1.8.0")]
3872        impl<$($life),*> PartialOrd<$rhs> for $lhs {
3873            #[inline]
3874            fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
3875                <Path as PartialOrd>::partial_cmp(self, other.as_ref())
3876            }
3877        }
3878
3879        #[stable(feature = "cmp_path", since = "1.8.0")]
3880        impl<$($life),*> PartialOrd<$lhs> for $rhs {
3881            #[inline]
3882            fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
3883                <Path as PartialOrd>::partial_cmp(self.as_ref(), other)
3884            }
3885        }
3886    };
3887}
3888
3889impl_cmp_os_str!(<> PathBuf, OsStr);
3890impl_cmp_os_str!(<'a> PathBuf, &'a OsStr);
3891impl_cmp_os_str!(<'a> PathBuf, Cow<'a, OsStr>);
3892impl_cmp_os_str!(<> PathBuf, OsString);
3893impl_cmp_os_str!(<> Path, OsStr);
3894impl_cmp_os_str!(<'a> Path, &'a OsStr);
3895impl_cmp_os_str!(<'a> Path, Cow<'a, OsStr>);
3896impl_cmp_os_str!(<> Path, OsString);
3897impl_cmp_os_str!(<'a> &'a Path, OsStr);
3898impl_cmp_os_str!(<'a, 'b> &'a Path, Cow<'b, OsStr>);
3899impl_cmp_os_str!(<'a> &'a Path, OsString);
3900impl_cmp_os_str!(<'a> Cow<'a, Path>, OsStr);
3901impl_cmp_os_str!(<'a, 'b> Cow<'a, Path>, &'b OsStr);
3902impl_cmp_os_str!(<'a> Cow<'a, Path>, OsString);
3903
3904#[stable(since = "1.7.0", feature = "strip_prefix")]
3905impl fmt::Display for StripPrefixError {
3906    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3907        "prefix not found".fmt(f)
3908    }
3909}
3910
3911#[stable(since = "1.7.0", feature = "strip_prefix")]
3912impl Error for StripPrefixError {}
3913
3914#[unstable(feature = "normalize_lexically", issue = "134694")]
3915impl fmt::Display for NormalizeError {
3916    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3917        f.write_str("parent reference `..` points outside of base directory")
3918    }
3919}
3920#[unstable(feature = "normalize_lexically", issue = "134694")]
3921impl Error for NormalizeError {}
3922
3923/// Makes the path absolute without accessing the filesystem.
3924///
3925/// If the path is relative, the current directory is used as the base directory.
3926/// All intermediate components will be resolved according to platform-specific
3927/// rules, but unlike [`canonicalize`][crate::fs::canonicalize], this does not
3928/// resolve symlinks and may succeed even if the path does not exist.
3929///
3930/// If the `path` is empty or getting the
3931/// [current directory][crate::env::current_dir] fails, then an error will be
3932/// returned.
3933///
3934/// # Platform-specific behavior
3935///
3936/// On POSIX platforms, the path is resolved using [POSIX semantics][posix-semantics],
3937/// except that it stops short of resolving symlinks. This means it will keep `..`
3938/// components and trailing separators.
3939///
3940/// On Windows, for verbatim paths, this will simply return the path as given. For other
3941/// paths, this is currently equivalent to calling
3942/// [`GetFullPathNameW`][windows-path].
3943///
3944/// On Cygwin, this is currently equivalent to calling [`cygwin_conv_path`][cygwin-path]
3945/// with mode `CCP_WIN_A_TO_POSIX`, and then being processed like other POSIX platforms.
3946/// If a Windows path is given, it will be converted to an absolute POSIX path without
3947/// keeping `..`.
3948///
3949/// Note that these [may change in the future][changes].
3950///
3951/// # Errors
3952///
3953/// This function may return an error in the following situations:
3954///
3955/// * If `path` is syntactically invalid; in particular, if it is empty.
3956/// * If getting the [current directory][crate::env::current_dir] fails.
3957///
3958/// # Examples
3959///
3960/// ## POSIX paths
3961///
3962/// ```
3963/// # #[cfg(unix)]
3964/// fn main() -> std::io::Result<()> {
3965///     use std::path::{self, Path};
3966///
3967///     // Relative to absolute
3968///     let absolute = path::absolute("foo/./bar")?;
3969///     assert!(absolute.ends_with("foo/bar"));
3970///
3971///     // Absolute to absolute
3972///     let absolute = path::absolute("/foo//test/.././bar.rs")?;
3973///     assert_eq!(absolute, Path::new("/foo/test/../bar.rs"));
3974///     Ok(())
3975/// }
3976/// # #[cfg(not(unix))]
3977/// # fn main() {}
3978/// ```
3979///
3980/// ## Windows paths
3981///
3982/// ```
3983/// # #[cfg(windows)]
3984/// fn main() -> std::io::Result<()> {
3985///     use std::path::{self, Path};
3986///
3987///     // Relative to absolute
3988///     let absolute = path::absolute("foo/./bar")?;
3989///     assert!(absolute.ends_with(r"foo\bar"));
3990///
3991///     // Absolute to absolute
3992///     let absolute = path::absolute(r"C:\foo//test\..\./bar.rs")?;
3993///
3994///     assert_eq!(absolute, Path::new(r"C:\foo\bar.rs"));
3995///     Ok(())
3996/// }
3997/// # #[cfg(not(windows))]
3998/// # fn main() {}
3999/// ```
4000///
4001/// Note that this [may change in the future][changes].
4002///
4003/// [changes]: io#platform-specific-behavior
4004/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
4005/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew
4006/// [cygwin-path]: https://cygwin.com/cygwin-api/func-cygwin-conv-path.html
4007#[stable(feature = "absolute_path", since = "1.79.0")]
4008pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
4009    let path = path.as_ref();
4010    if path.as_os_str().is_empty() {
4011        Err(io::const_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute"))
4012    } else {
4013        sys::path::absolute(path)
4014    }
4015}