std/
path.rs

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