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