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