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