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