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