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

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy