1 //! Cross-platform path manipulation.
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.
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.
17 //! Path manipulation includes both parsing components from slices and building
20 //! To parse a path, you can create a [`Path`] slice from a [`str`]
21 //! slice and start asking questions:
24 //! use std::path::Path;
25 //! use std::ffi::OsStr;
27 //! let path = Path::new("/tmp/foo/bar.txt");
29 //! let parent = path.parent();
30 //! assert_eq!(parent, Some(Path::new("/tmp/foo")));
32 //! let file_stem = path.file_stem();
33 //! assert_eq!(file_stem, Some(OsStr::new("bar")));
35 //! let extension = path.extension();
36 //! assert_eq!(extension, Some(OsStr::new("txt")));
39 //! To build or modify paths, use [`PathBuf`]:
42 //! use std::path::PathBuf;
44 //! // This way works...
45 //! let mut path = PathBuf::from("c:\\");
47 //! path.push("windows");
48 //! path.push("system32");
50 //! path.set_extension("dll");
52 //! // ... but push is best used if you don't know everything up
53 //! // front. If you do, this way is better:
54 //! let path: PathBuf = ["c:\\", "windows", "system32.dll"].iter().collect();
57 //! [`components`]: Path::components
58 //! [`push`]: PathBuf::push
60 #![stable(feature = "rust1", since = "1.0.0")]
61 #![deny(unsafe_op_in_unsafe_fn)]
66 use crate::borrow
::{Borrow, Cow}
;
68 use crate::error
::Error
;
71 use crate::hash
::{Hash, Hasher}
;
73 use crate::iter
::{self, FusedIterator}
;
74 use crate::ops
::{self, Deref}
;
76 use crate::str::FromStr
;
79 use crate::ffi
::{OsStr, OsString}
;
81 use crate::sys
::path
::{is_sep_byte, is_verbatim_sep, parse_prefix, MAIN_SEP_STR}
;
83 ////////////////////////////////////////////////////////////////////////////////
85 ////////////////////////////////////////////////////////////////////////////////
87 // Parsing in this module is done by directly transmuting OsStr to [u8] slices,
88 // taking advantage of the fact that OsStr always encodes ASCII characters
89 // as-is. Eventually, this transmutation should be replaced by direct uses of
90 // OsStr APIs for parsing, but it will take a while for those to become
93 ////////////////////////////////////////////////////////////////////////////////
95 ////////////////////////////////////////////////////////////////////////////////
97 /// Windows path prefixes, e.g., `C:` or `\\server\share`.
99 /// Windows uses a variety of path prefix styles, including references to drive
100 /// volumes (like `C:`), network shared folders (like `\\server\share`), and
101 /// others. In addition, some path prefixes are "verbatim" (i.e., prefixed with
102 /// `\\?\`), in which case `/` is *not* treated as a separator and essentially
103 /// no normalization is performed.
108 /// use std::path::{Component, Path, Prefix};
109 /// use std::path::Prefix::*;
110 /// use std::ffi::OsStr;
112 /// fn get_path_prefix(s: &str) -> Prefix {
113 /// let path = Path::new(s);
114 /// match path.components().next().unwrap() {
115 /// Component::Prefix(prefix_component) => prefix_component.kind(),
120 /// # if cfg!(windows) {
121 /// assert_eq!(Verbatim(OsStr::new("pictures")),
122 /// get_path_prefix(r"\\?\pictures\kittens"));
123 /// assert_eq!(VerbatimUNC(OsStr::new("server"), OsStr::new("share")),
124 /// get_path_prefix(r"\\?\UNC\server\share"));
125 /// assert_eq!(VerbatimDisk(b'C'), get_path_prefix(r"\\?\c:\"));
126 /// assert_eq!(DeviceNS(OsStr::new("BrainInterface")),
127 /// get_path_prefix(r"\\.\BrainInterface"));
128 /// assert_eq!(UNC(OsStr::new("server"), OsStr::new("share")),
129 /// get_path_prefix(r"\\server\share"));
130 /// assert_eq!(Disk(b'C'), get_path_prefix(r"C:\Users\Rust\Pictures\Ferris"));
133 #[derive(Copy, Clone, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]
134 #[stable(feature = "rust1", since = "1.0.0")]
135 pub enum Prefix
<'a
> {
136 /// Verbatim prefix, e.g., `\\?\cat_pics`.
138 /// Verbatim prefixes consist of `\\?\` immediately followed by the given
140 #[stable(feature = "rust1", since = "1.0.0")]
141 Verbatim(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
143 /// Verbatim prefix using Windows' _**U**niform **N**aming **C**onvention_,
144 /// e.g., `\\?\UNC\server\share`.
146 /// Verbatim UNC prefixes consist of `\\?\UNC\` immediately followed by the
147 /// server's hostname and a share name.
148 #[stable(feature = "rust1", since = "1.0.0")]
150 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
151 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
154 /// Verbatim disk prefix, e.g., `\\?\C:`.
156 /// Verbatim disk prefixes consist of `\\?\` immediately followed by the
157 /// drive letter and `:`.
158 #[stable(feature = "rust1", since = "1.0.0")]
159 VerbatimDisk(#[stable(feature = "rust1", since = "1.0.0")] u8),
161 /// Device namespace prefix, e.g., `\\.\COM42`.
163 /// Device namespace prefixes consist of `\\.\` immediately followed by the
165 #[stable(feature = "rust1", since = "1.0.0")]
166 DeviceNS(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
168 /// Prefix using Windows' _**U**niform **N**aming **C**onvention_, e.g.
169 /// `\\server\share`.
171 /// UNC prefixes consist of the server's hostname and a share name.
172 #[stable(feature = "rust1", since = "1.0.0")]
174 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
175 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
178 /// Prefix `C:` for the given disk drive.
179 #[stable(feature = "rust1", since = "1.0.0")]
180 Disk(#[stable(feature = "rust1", since = "1.0.0")] u8),
183 impl<'a
> Prefix
<'a
> {
185 fn len(&self) -> usize {
187 fn os_str_len(s
: &OsStr
) -> usize {
188 os_str_as_u8_slice(s
).len()
191 Verbatim(x
) => 4 + os_str_len(x
),
192 VerbatimUNC(x
, y
) => {
193 8 + os_str_len(x
) + if os_str_len(y
) > 0 { 1 + os_str_len(y) }
else { 0 }
195 VerbatimDisk(_
) => 6,
196 UNC(x
, y
) => 2 + os_str_len(x
) + if os_str_len(y
) > 0 { 1 + os_str_len(y) }
else { 0 }
,
197 DeviceNS(x
) => 4 + os_str_len(x
),
202 /// Determines if the prefix is verbatim, i.e., begins with `\\?\`.
207 /// use std::path::Prefix::*;
208 /// use std::ffi::OsStr;
210 /// assert!(Verbatim(OsStr::new("pictures")).is_verbatim());
211 /// assert!(VerbatimUNC(OsStr::new("server"), OsStr::new("share")).is_verbatim());
212 /// assert!(VerbatimDisk(b'C').is_verbatim());
213 /// assert!(!DeviceNS(OsStr::new("BrainInterface")).is_verbatim());
214 /// assert!(!UNC(OsStr::new("server"), OsStr::new("share")).is_verbatim());
215 /// assert!(!Disk(b'C').is_verbatim());
219 #[stable(feature = "rust1", since = "1.0.0")]
220 pub fn is_verbatim(&self) -> bool
{
222 matches
!(*self, Verbatim(_
) | VerbatimDisk(_
) | VerbatimUNC(..))
226 fn is_drive(&self) -> bool
{
227 matches
!(*self, Prefix
::Disk(_
))
231 fn has_implicit_root(&self) -> bool
{
236 ////////////////////////////////////////////////////////////////////////////////
237 // Exposed parsing helpers
238 ////////////////////////////////////////////////////////////////////////////////
240 /// Determines whether the character is one of the permitted path
241 /// separators for the current platform.
248 /// assert!(path::is_separator('/')); // '/' works for both Unix and Windows
249 /// assert!(!path::is_separator('❤'));
252 #[stable(feature = "rust1", since = "1.0.0")]
253 pub fn is_separator(c
: char) -> bool
{
254 c
.is_ascii() && is_sep_byte(c
as u8)
257 /// The primary separator of path components for the current platform.
259 /// For example, `/` on Unix and `\` on Windows.
260 #[stable(feature = "rust1", since = "1.0.0")]
261 pub const MAIN_SEPARATOR
: char = crate::sys
::path
::MAIN_SEP
;
263 ////////////////////////////////////////////////////////////////////////////////
265 ////////////////////////////////////////////////////////////////////////////////
267 // Iterate through `iter` while it matches `prefix`; return `None` if `prefix`
268 // is not a prefix of `iter`, otherwise return `Some(iter_after_prefix)` giving
269 // `iter` after having exhausted `prefix`.
270 fn iter_after
<'a
, 'b
, I
, J
>(mut iter
: I
, mut prefix
: J
) -> Option
<I
>
272 I
: Iterator
<Item
= Component
<'a
>> + Clone
,
273 J
: Iterator
<Item
= Component
<'b
>>,
276 let mut iter_next
= iter
.clone();
277 match (iter_next
.next(), prefix
.next()) {
278 (Some(ref x
), Some(ref y
)) if x
== y
=> (),
279 (Some(_
), Some(_
)) => return None
,
280 (Some(_
), None
) => return Some(iter
),
281 (None
, None
) => return Some(iter
),
282 (None
, Some(_
)) => return None
,
288 // See note at the top of this module to understand why these are used:
290 // These casts are safe as OsStr is internally a wrapper around [u8] on all
293 // Note that currently this relies on the special knowledge that libstd has;
294 // these types are single-element structs but are not marked repr(transparent)
295 // or repr(C) which would make these casts allowable outside std.
296 fn os_str_as_u8_slice(s
: &OsStr
) -> &[u8] {
297 unsafe { &*(s as *const OsStr as *const [u8]) }
299 unsafe fn u8_slice_as_os_str(s
: &[u8]) -> &OsStr
{
300 // SAFETY: see the comment of `os_str_as_u8_slice`
301 unsafe { &*(s as *const [u8] as *const OsStr) }
304 // Detect scheme on Redox
305 fn has_redox_scheme(s
: &[u8]) -> bool
{
306 cfg
!(target_os
= "redox") && s
.contains(&b'
:'
)
309 ////////////////////////////////////////////////////////////////////////////////
310 // Cross-platform, iterator-independent parsing
311 ////////////////////////////////////////////////////////////////////////////////
313 /// Says whether the first byte after the prefix is a separator.
314 fn has_physical_root(s
: &[u8], prefix
: Option
<Prefix
<'_
>>) -> bool
{
315 let path
= if let Some(p
) = prefix { &s[p.len()..] }
else { s }
;
316 !path
.is_empty() && is_sep_byte(path
[0])
319 // basic workhorse for splitting stem and extension
320 fn rsplit_file_at_dot(file
: &OsStr
) -> (Option
<&OsStr
>, Option
<&OsStr
>) {
321 if os_str_as_u8_slice(file
) == b
".." {
322 return (Some(file
), None
);
325 // The unsafety here stems from converting between &OsStr and &[u8]
326 // and back. This is safe to do because (1) we only look at ASCII
327 // contents of the encoding and (2) new &OsStr values are produced
328 // only from ASCII-bounded slices of existing &OsStr values.
329 let mut iter
= os_str_as_u8_slice(file
).rsplitn(2, |b
| *b
== b'
.'
);
330 let after
= iter
.next();
331 let before
= iter
.next();
332 if before
== Some(b
"") {
335 unsafe { (before.map(|s| u8_slice_as_os_str(s)), after.map(|s| u8_slice_as_os_str(s))) }
339 fn split_file_at_dot(file
: &OsStr
) -> (&OsStr
, Option
<&OsStr
>) {
340 let slice
= os_str_as_u8_slice(file
);
345 // The unsafety here stems from converting between &OsStr and &[u8]
346 // and back. This is safe to do because (1) we only look at ASCII
347 // contents of the encoding and (2) new &OsStr values are produced
348 // only from ASCII-bounded slices of existing &OsStr values.
349 let i
= match slice
[1..].iter().position(|b
| *b
== b'
.'
) {
351 None
=> return (file
, None
),
353 let before
= &slice
[..i
];
354 let after
= &slice
[i
+ 1..];
355 unsafe { (u8_slice_as_os_str(before), Some(u8_slice_as_os_str(after))) }
358 ////////////////////////////////////////////////////////////////////////////////
359 // The core iterators
360 ////////////////////////////////////////////////////////////////////////////////
362 /// Component parsing works by a double-ended state machine; the cursors at the
363 /// front and back of the path each keep track of what parts of the path have
364 /// been consumed so far.
366 /// Going front to back, a path is made up of a prefix, a starting
367 /// directory component, and a body (of normal components)
368 #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
371 StartDir
= 1, // / or . or nothing
372 Body
= 2, // foo/bar/baz
376 /// A structure wrapping a Windows path prefix as well as its unparsed string
379 /// In addition to the parsed [`Prefix`] information returned by [`kind`],
380 /// `PrefixComponent` also holds the raw and unparsed [`OsStr`] slice,
381 /// returned by [`as_os_str`].
383 /// Instances of this `struct` can be obtained by matching against the
384 /// [`Prefix` variant] on [`Component`].
386 /// Does not occur on Unix.
391 /// # if cfg!(windows) {
392 /// use std::path::{Component, Path, Prefix};
393 /// use std::ffi::OsStr;
395 /// let path = Path::new(r"c:\you\later\");
396 /// match path.components().next().unwrap() {
397 /// Component::Prefix(prefix_component) => {
398 /// assert_eq!(Prefix::Disk(b'C'), prefix_component.kind());
399 /// assert_eq!(OsStr::new("c:"), prefix_component.as_os_str());
401 /// _ => unreachable!(),
406 /// [`as_os_str`]: PrefixComponent::as_os_str
407 /// [`kind`]: PrefixComponent::kind
408 /// [`Prefix` variant]: Component::Prefix
409 #[stable(feature = "rust1", since = "1.0.0")]
410 #[derive(Copy, Clone, Eq, Debug)]
411 pub struct PrefixComponent
<'a
> {
412 /// The prefix as an unparsed `OsStr` slice.
415 /// The parsed prefix data.
419 impl<'a
> PrefixComponent
<'a
> {
420 /// Returns the parsed prefix data.
422 /// See [`Prefix`]'s documentation for more information on the different
423 /// kinds of prefixes.
424 #[stable(feature = "rust1", since = "1.0.0")]
427 pub fn kind(&self) -> Prefix
<'a
> {
431 /// Returns the raw [`OsStr`] slice for this prefix.
432 #[stable(feature = "rust1", since = "1.0.0")]
435 pub fn as_os_str(&self) -> &'a OsStr
{
440 #[stable(feature = "rust1", since = "1.0.0")]
441 impl<'a
> cmp
::PartialEq
for PrefixComponent
<'a
> {
443 fn eq(&self, other
: &PrefixComponent
<'a
>) -> bool
{
444 cmp
::PartialEq
::eq(&self.parsed
, &other
.parsed
)
448 #[stable(feature = "rust1", since = "1.0.0")]
449 impl<'a
> cmp
::PartialOrd
for PrefixComponent
<'a
> {
451 fn partial_cmp(&self, other
: &PrefixComponent
<'a
>) -> Option
<cmp
::Ordering
> {
452 cmp
::PartialOrd
::partial_cmp(&self.parsed
, &other
.parsed
)
456 #[stable(feature = "rust1", since = "1.0.0")]
457 impl cmp
::Ord
for PrefixComponent
<'_
> {
459 fn cmp(&self, other
: &Self) -> cmp
::Ordering
{
460 cmp
::Ord
::cmp(&self.parsed
, &other
.parsed
)
464 #[stable(feature = "rust1", since = "1.0.0")]
465 impl Hash
for PrefixComponent
<'_
> {
466 fn hash
<H
: Hasher
>(&self, h
: &mut H
) {
471 /// A single component of a path.
473 /// A `Component` roughly corresponds to a substring between path separators
476 /// This `enum` is created by iterating over [`Components`], which in turn is
477 /// created by the [`components`](Path::components) method on [`Path`].
482 /// use std::path::{Component, Path};
484 /// let path = Path::new("/tmp/foo/bar.txt");
485 /// let components = path.components().collect::<Vec<_>>();
486 /// assert_eq!(&components, &[
487 /// Component::RootDir,
488 /// Component::Normal("tmp".as_ref()),
489 /// Component::Normal("foo".as_ref()),
490 /// Component::Normal("bar.txt".as_ref()),
493 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
494 #[stable(feature = "rust1", since = "1.0.0")]
495 pub enum Component
<'a
> {
496 /// A Windows path prefix, e.g., `C:` or `\\server\share`.
498 /// There is a large variety of prefix types, see [`Prefix`]'s documentation
501 /// Does not occur on Unix.
502 #[stable(feature = "rust1", since = "1.0.0")]
503 Prefix(#[stable(feature = "rust1", since = "1.0.0")] PrefixComponent<'a>),
505 /// The root directory component, appears after any prefix and before anything else.
507 /// It represents a separator that designates that a path starts from root.
508 #[stable(feature = "rust1", since = "1.0.0")]
511 /// A reference to the current directory, i.e., `.`.
512 #[stable(feature = "rust1", since = "1.0.0")]
515 /// A reference to the parent directory, i.e., `..`.
516 #[stable(feature = "rust1", since = "1.0.0")]
519 /// A normal component, e.g., `a` and `b` in `a/b`.
521 /// This variant is the most common one, it represents references to files
523 #[stable(feature = "rust1", since = "1.0.0")]
524 Normal(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
527 impl<'a
> Component
<'a
> {
528 /// Extracts the underlying [`OsStr`] slice.
533 /// use std::path::Path;
535 /// let path = Path::new("./tmp/foo/bar.txt");
536 /// let components: Vec<_> = path.components().map(|comp| comp.as_os_str()).collect();
537 /// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
539 #[must_use = "`self` will be dropped if the result is not used"]
540 #[stable(feature = "rust1", since = "1.0.0")]
541 pub fn as_os_str(self) -> &'a OsStr
{
543 Component
::Prefix(p
) => p
.as_os_str(),
544 Component
::RootDir
=> OsStr
::new(MAIN_SEP_STR
),
545 Component
::CurDir
=> OsStr
::new("."),
546 Component
::ParentDir
=> OsStr
::new(".."),
547 Component
::Normal(path
) => path
,
552 #[stable(feature = "rust1", since = "1.0.0")]
553 impl AsRef
<OsStr
> for Component
<'_
> {
555 fn as_ref(&self) -> &OsStr
{
560 #[stable(feature = "path_component_asref", since = "1.25.0")]
561 impl AsRef
<Path
> for Component
<'_
> {
563 fn as_ref(&self) -> &Path
{
564 self.as_os_str().as_ref()
568 /// An iterator over the [`Component`]s of a [`Path`].
570 /// This `struct` is created by the [`components`] method on [`Path`].
571 /// See its documentation for more.
576 /// use std::path::Path;
578 /// let path = Path::new("/tmp/foo/bar.txt");
580 /// for component in path.components() {
581 /// println!("{:?}", component);
585 /// [`components`]: Path::components
587 #[must_use = "iterators are lazy and do nothing unless consumed"]
588 #[stable(feature = "rust1", since = "1.0.0")]
589 pub struct Components
<'a
> {
590 // The path left to parse components from
593 // The prefix as it was originally parsed, if any
594 prefix
: Option
<Prefix
<'a
>>,
596 // true if path *physically* has a root separator; for most Windows
597 // prefixes, it may have a "logical" root separator for the purposes of
598 // normalization, e.g., \\server\share == \\server\share\.
599 has_physical_root
: bool
,
601 // The iterator is double-ended, and these two states keep track of what has
602 // been produced from either end
607 /// An iterator over the [`Component`]s of a [`Path`], as [`OsStr`] slices.
609 /// This `struct` is created by the [`iter`] method on [`Path`].
610 /// See its documentation for more.
612 /// [`iter`]: Path::iter
614 #[must_use = "iterators are lazy and do nothing unless consumed"]
615 #[stable(feature = "rust1", since = "1.0.0")]
616 pub struct Iter
<'a
> {
617 inner
: Components
<'a
>,
620 #[stable(feature = "path_components_debug", since = "1.13.0")]
621 impl fmt
::Debug
for Components
<'_
> {
622 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
623 struct DebugHelper
<'a
>(&'a Path
);
625 impl fmt
::Debug
for DebugHelper
<'_
> {
626 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
627 f
.debug_list().entries(self.0.components()).finish()
631 f
.debug_tuple("Components").field(&DebugHelper(self.as_path())).finish()
635 impl<'a
> Components
<'a
> {
636 // how long is the prefix, if any?
638 fn prefix_len(&self) -> usize {
639 self.prefix
.as_ref().map(Prefix
::len
).unwrap_or(0)
643 fn prefix_verbatim(&self) -> bool
{
644 self.prefix
.as_ref().map(Prefix
::is_verbatim
).unwrap_or(false)
647 /// how much of the prefix is left from the point of view of iteration?
649 fn prefix_remaining(&self) -> usize {
650 if self.front
== State
::Prefix { self.prefix_len() }
else { 0 }
653 // Given the iteration so far, how much of the pre-State::Body path is left?
655 fn len_before_body(&self) -> usize {
656 let root
= if self.front
<= State
::StartDir
&& self.has_physical_root { 1 }
else { 0 }
;
657 let cur_dir
= if self.front
<= State
::StartDir
&& self.include_cur_dir() { 1 }
else { 0 }
;
658 self.prefix_remaining() + root
+ cur_dir
661 // is the iteration complete?
663 fn finished(&self) -> bool
{
664 self.front
== State
::Done
|| self.back
== State
::Done
|| self.front
> self.back
668 fn is_sep_byte(&self, b
: u8) -> bool
{
669 if self.prefix_verbatim() { is_verbatim_sep(b) }
else { is_sep_byte(b) }
672 /// Extracts a slice corresponding to the portion of the path remaining for iteration.
677 /// use std::path::Path;
679 /// let mut components = Path::new("/tmp/foo/bar.txt").components();
680 /// components.next();
681 /// components.next();
683 /// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
686 #[stable(feature = "rust1", since = "1.0.0")]
687 pub fn as_path(&self) -> &'a Path
{
688 let mut comps
= self.clone();
689 if comps
.front
== State
::Body
{
692 if comps
.back
== State
::Body
{
695 unsafe { Path::from_u8_slice(comps.path) }
698 /// Is the *original* path rooted?
699 fn has_root(&self) -> bool
{
700 if self.has_physical_root
{
703 if let Some(p
) = self.prefix
{
704 if p
.has_implicit_root() {
711 /// Should the normalized path include a leading . ?
712 fn include_cur_dir(&self) -> bool
{
716 let mut iter
= self.path
[self.prefix_len()..].iter();
717 match (iter
.next(), iter
.next()) {
718 (Some(&b'
.'
), None
) => true,
719 (Some(&b'
.'
), Some(&b
)) => self.is_sep_byte(b
),
724 // parse a given byte sequence into the corresponding path component
725 fn parse_single_component
<'b
>(&self, comp
: &'b
[u8]) -> Option
<Component
<'b
>> {
727 b
"." if self.prefix_verbatim() => Some(Component
::CurDir
),
728 b
"." => None
, // . components are normalized away, except at
729 // the beginning of a path, which is treated
730 // separately via `include_cur_dir`
731 b
".." => Some(Component
::ParentDir
),
733 _
=> Some(Component
::Normal(unsafe { u8_slice_as_os_str(comp) }
)),
737 // parse a component from the left, saying how many bytes to consume to
738 // remove the component
739 fn parse_next_component(&self) -> (usize, Option
<Component
<'a
>>) {
740 debug_assert
!(self.front
== State
::Body
);
741 let (extra
, comp
) = match self.path
.iter().position(|b
| self.is_sep_byte(*b
)) {
742 None
=> (0, self.path
),
743 Some(i
) => (1, &self.path
[..i
]),
745 (comp
.len() + extra
, self.parse_single_component(comp
))
748 // parse a component from the right, saying how many bytes to consume to
749 // remove the component
750 fn parse_next_component_back(&self) -> (usize, Option
<Component
<'a
>>) {
751 debug_assert
!(self.back
== State
::Body
);
752 let start
= self.len_before_body();
753 let (extra
, comp
) = match self.path
[start
..].iter().rposition(|b
| self.is_sep_byte(*b
)) {
754 None
=> (0, &self.path
[start
..]),
755 Some(i
) => (1, &self.path
[start
+ i
+ 1..]),
757 (comp
.len() + extra
, self.parse_single_component(comp
))
760 // trim away repeated separators (i.e., empty components) on the left
761 fn trim_left(&mut self) {
762 while !self.path
.is_empty() {
763 let (size
, comp
) = self.parse_next_component();
767 self.path
= &self.path
[size
..];
772 // trim away repeated separators (i.e., empty components) on the right
773 fn trim_right(&mut self) {
774 while self.path
.len() > self.len_before_body() {
775 let (size
, comp
) = self.parse_next_component_back();
779 self.path
= &self.path
[..self.path
.len() - size
];
785 #[stable(feature = "rust1", since = "1.0.0")]
786 impl AsRef
<Path
> for Components
<'_
> {
788 fn as_ref(&self) -> &Path
{
793 #[stable(feature = "rust1", since = "1.0.0")]
794 impl AsRef
<OsStr
> for Components
<'_
> {
796 fn as_ref(&self) -> &OsStr
{
797 self.as_path().as_os_str()
801 #[stable(feature = "path_iter_debug", since = "1.13.0")]
802 impl fmt
::Debug
for Iter
<'_
> {
803 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
804 struct DebugHelper
<'a
>(&'a Path
);
806 impl fmt
::Debug
for DebugHelper
<'_
> {
807 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
808 f
.debug_list().entries(self.0.iter
()).finish()
812 f
.debug_tuple("Iter").field(&DebugHelper(self.as_path())).finish()
817 /// Extracts a slice corresponding to the portion of the path remaining for iteration.
822 /// use std::path::Path;
824 /// let mut iter = Path::new("/tmp/foo/bar.txt").iter();
828 /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
830 #[stable(feature = "rust1", since = "1.0.0")]
833 pub fn as_path(&self) -> &'a Path
{
838 #[stable(feature = "rust1", since = "1.0.0")]
839 impl AsRef
<Path
> for Iter
<'_
> {
841 fn as_ref(&self) -> &Path
{
846 #[stable(feature = "rust1", since = "1.0.0")]
847 impl AsRef
<OsStr
> for Iter
<'_
> {
849 fn as_ref(&self) -> &OsStr
{
850 self.as_path().as_os_str()
854 #[stable(feature = "rust1", since = "1.0.0")]
855 impl<'a
> Iterator
for Iter
<'a
> {
856 type Item
= &'a OsStr
;
859 fn next(&mut self) -> Option
<&'a OsStr
> {
860 self.inner
.next().map(Component
::as_os_str
)
864 #[stable(feature = "rust1", since = "1.0.0")]
865 impl<'a
> DoubleEndedIterator
for Iter
<'a
> {
867 fn next_back(&mut self) -> Option
<&'a OsStr
> {
868 self.inner
.next_back().map(Component
::as_os_str
)
872 #[stable(feature = "fused", since = "1.26.0")]
873 impl FusedIterator
for Iter
<'_
> {}
875 #[stable(feature = "rust1", since = "1.0.0")]
876 impl<'a
> Iterator
for Components
<'a
> {
877 type Item
= Component
<'a
>;
879 fn next(&mut self) -> Option
<Component
<'a
>> {
880 while !self.finished() {
882 State
::Prefix
if self.prefix_len() > 0 => {
883 self.front
= State
::StartDir
;
884 debug_assert
!(self.prefix_len() <= self.path
.len());
885 let raw
= &self.path
[..self.prefix_len()];
886 self.path
= &self.path
[self.prefix_len()..];
887 return Some(Component
::Prefix(PrefixComponent
{
888 raw
: unsafe { u8_slice_as_os_str(raw) }
,
889 parsed
: self.prefix
.unwrap(),
893 self.front
= State
::StartDir
;
896 self.front
= State
::Body
;
897 if self.has_physical_root
{
898 debug_assert
!(!self.path
.is_empty());
899 self.path
= &self.path
[1..];
900 return Some(Component
::RootDir
);
901 } else if let Some(p
) = self.prefix
{
902 if p
.has_implicit_root() && !p
.is_verbatim() {
903 return Some(Component
::RootDir
);
905 } else if self.include_cur_dir() {
906 debug_assert
!(!self.path
.is_empty());
907 self.path
= &self.path
[1..];
908 return Some(Component
::CurDir
);
911 State
::Body
if !self.path
.is_empty() => {
912 let (size
, comp
) = self.parse_next_component();
913 self.path
= &self.path
[size
..];
919 self.front
= State
::Done
;
921 State
::Done
=> unreachable
!(),
928 #[stable(feature = "rust1", since = "1.0.0")]
929 impl<'a
> DoubleEndedIterator
for Components
<'a
> {
930 fn next_back(&mut self) -> Option
<Component
<'a
>> {
931 while !self.finished() {
933 State
::Body
if self.path
.len() > self.len_before_body() => {
934 let (size
, comp
) = self.parse_next_component_back();
935 self.path
= &self.path
[..self.path
.len() - size
];
941 self.back
= State
::StartDir
;
944 self.back
= State
::Prefix
;
945 if self.has_physical_root
{
946 self.path
= &self.path
[..self.path
.len() - 1];
947 return Some(Component
::RootDir
);
948 } else if let Some(p
) = self.prefix
{
949 if p
.has_implicit_root() && !p
.is_verbatim() {
950 return Some(Component
::RootDir
);
952 } else if self.include_cur_dir() {
953 self.path
= &self.path
[..self.path
.len() - 1];
954 return Some(Component
::CurDir
);
957 State
::Prefix
if self.prefix_len() > 0 => {
958 self.back
= State
::Done
;
959 return Some(Component
::Prefix(PrefixComponent
{
960 raw
: unsafe { u8_slice_as_os_str(self.path) }
,
961 parsed
: self.prefix
.unwrap(),
965 self.back
= State
::Done
;
968 State
::Done
=> unreachable
!(),
975 #[stable(feature = "fused", since = "1.26.0")]
976 impl FusedIterator
for Components
<'_
> {}
978 #[stable(feature = "rust1", since = "1.0.0")]
979 impl<'a
> cmp
::PartialEq
for Components
<'a
> {
981 fn eq(&self, other
: &Components
<'a
>) -> bool
{
982 let Components { path: _, front: _, back: _, has_physical_root: _, prefix: _ }
= self;
984 // Fast path for exact matches, e.g. for hashmap lookups.
985 // Don't explicitly compare the prefix or has_physical_root fields since they'll
986 // either be covered by the `path` buffer or are only relevant for `prefix_verbatim()`.
987 if self.path
.len() == other
.path
.len()
988 && self.front
== other
.front
989 && self.back
== State
::Body
990 && other
.back
== State
::Body
991 && self.prefix_verbatim() == other
.prefix_verbatim()
993 // possible future improvement: this could bail out earlier if there were a
994 // reverse memcmp/bcmp comparing back to front
995 if self.path
== other
.path
{
1000 // compare back to front since absolute paths often share long prefixes
1001 Iterator
::eq(self.clone().rev(), other
.clone().rev())
1005 #[stable(feature = "rust1", since = "1.0.0")]
1006 impl cmp
::Eq
for Components
<'_
> {}
1008 #[stable(feature = "rust1", since = "1.0.0")]
1009 impl<'a
> cmp
::PartialOrd
for Components
<'a
> {
1011 fn partial_cmp(&self, other
: &Components
<'a
>) -> Option
<cmp
::Ordering
> {
1012 Some(compare_components(self.clone(), other
.clone()))
1016 #[stable(feature = "rust1", since = "1.0.0")]
1017 impl cmp
::Ord
for Components
<'_
> {
1019 fn cmp(&self, other
: &Self) -> cmp
::Ordering
{
1020 compare_components(self.clone(), other
.clone())
1024 fn compare_components(mut left
: Components
<'_
>, mut right
: Components
<'_
>) -> cmp
::Ordering
{
1025 // Fast path for long shared prefixes
1027 // - compare raw bytes to find first mismatch
1028 // - backtrack to find separator before mismatch to avoid ambiguous parsings of '.' or '..' characters
1029 // - if found update state to only do a component-wise comparison on the remainder,
1030 // otherwise do it on the full path
1032 // The fast path isn't taken for paths with a PrefixComponent to avoid backtracking into
1033 // the middle of one
1034 if left
.prefix
.is_none() && right
.prefix
.is_none() && left
.front
== right
.front
{
1035 // possible future improvement: a [u8]::first_mismatch simd implementation
1036 let first_difference
= match left
.path
.iter().zip(right
.path
).position(|(&a
, &b
)| a
!= b
) {
1037 None
if left
.path
.len() == right
.path
.len() => return cmp
::Ordering
::Equal
,
1038 None
=> left
.path
.len().min(right
.path
.len()),
1042 if let Some(previous_sep
) =
1043 left
.path
[..first_difference
].iter().rposition(|&b
| left
.is_sep_byte(b
))
1045 let mismatched_component_start
= previous_sep
+ 1;
1046 left
.path
= &left
.path
[mismatched_component_start
..];
1047 left
.front
= State
::Body
;
1048 right
.path
= &right
.path
[mismatched_component_start
..];
1049 right
.front
= State
::Body
;
1053 Iterator
::cmp(left
, right
)
1056 /// An iterator over [`Path`] and its ancestors.
1058 /// This `struct` is created by the [`ancestors`] method on [`Path`].
1059 /// See its documentation for more.
1064 /// use std::path::Path;
1066 /// let path = Path::new("/foo/bar");
1068 /// for ancestor in path.ancestors() {
1069 /// println!("{}", ancestor.display());
1073 /// [`ancestors`]: Path::ancestors
1074 #[derive(Copy, Clone, Debug)]
1075 #[must_use = "iterators are lazy and do nothing unless consumed"]
1076 #[stable(feature = "path_ancestors", since = "1.28.0")]
1077 pub struct Ancestors
<'a
> {
1078 next
: Option
<&'a Path
>,
1081 #[stable(feature = "path_ancestors", since = "1.28.0")]
1082 impl<'a
> Iterator
for Ancestors
<'a
> {
1083 type Item
= &'a Path
;
1086 fn next(&mut self) -> Option
<Self::Item
> {
1087 let next
= self.next
;
1088 self.next
= next
.and_then(Path
::parent
);
1093 #[stable(feature = "path_ancestors", since = "1.28.0")]
1094 impl FusedIterator
for Ancestors
<'_
> {}
1096 ////////////////////////////////////////////////////////////////////////////////
1097 // Basic types and traits
1098 ////////////////////////////////////////////////////////////////////////////////
1100 /// An owned, mutable path (akin to [`String`]).
1102 /// This type provides methods like [`push`] and [`set_extension`] that mutate
1103 /// the path in place. It also implements [`Deref`] to [`Path`], meaning that
1104 /// all methods on [`Path`] slices are available on `PathBuf` values as well.
1106 /// [`push`]: PathBuf::push
1107 /// [`set_extension`]: PathBuf::set_extension
1109 /// More details about the overall approach can be found in
1110 /// the [module documentation](self).
1114 /// You can use [`push`] to build up a `PathBuf` from
1118 /// use std::path::PathBuf;
1120 /// let mut path = PathBuf::new();
1122 /// path.push(r"C:\");
1123 /// path.push("windows");
1124 /// path.push("system32");
1126 /// path.set_extension("dll");
1129 /// However, [`push`] is best used for dynamic situations. This is a better way
1130 /// to do this when you know all of the components ahead of time:
1133 /// use std::path::PathBuf;
1135 /// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
1138 /// We can still do better than this! Since these are all strings, we can use
1142 /// use std::path::PathBuf;
1144 /// let path = PathBuf::from(r"C:\windows\system32.dll");
1147 /// Which method works best depends on what kind of situation you're in.
1148 #[cfg_attr(not(test), rustc_diagnostic_item = "PathBuf")]
1149 #[stable(feature = "rust1", since = "1.0.0")]
1151 // `PathBuf::as_mut_vec` current implementation relies
1152 // on `PathBuf` being layout-compatible with `Vec<u8>`.
1153 // When attribute privacy is implemented, `PathBuf` should be annotated as `#[repr(transparent)]`.
1154 // Anyway, `PathBuf` representation and layout are considered implementation detail, are
1155 // not documented and must not be relied upon.
1156 pub struct PathBuf
{
1162 fn as_mut_vec(&mut self) -> &mut Vec
<u8> {
1163 unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) }
1166 /// Allocates an empty `PathBuf`.
1171 /// use std::path::PathBuf;
1173 /// let path = PathBuf::new();
1175 #[stable(feature = "rust1", since = "1.0.0")]
1178 pub fn new() -> PathBuf
{
1179 PathBuf { inner: OsString::new() }
1182 /// Creates a new `PathBuf` with a given capacity used to create the
1183 /// internal [`OsString`]. See [`with_capacity`] defined on [`OsString`].
1188 /// use std::path::PathBuf;
1190 /// let mut path = PathBuf::with_capacity(10);
1191 /// let capacity = path.capacity();
1193 /// // This push is done without reallocating
1194 /// path.push(r"C:\");
1196 /// assert_eq!(capacity, path.capacity());
1199 /// [`with_capacity`]: OsString::with_capacity
1200 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1203 pub fn with_capacity(capacity
: usize) -> PathBuf
{
1204 PathBuf { inner: OsString::with_capacity(capacity) }
1207 /// Coerces to a [`Path`] slice.
1212 /// use std::path::{Path, PathBuf};
1214 /// let p = PathBuf::from("/test");
1215 /// assert_eq!(Path::new("/test"), p.as_path());
1217 #[stable(feature = "rust1", since = "1.0.0")]
1220 pub fn as_path(&self) -> &Path
{
1224 /// Extends `self` with `path`.
1226 /// If `path` is absolute, it replaces the current path.
1230 /// * if `path` has a root but no prefix (e.g., `\windows`), it
1231 /// replaces everything except for the prefix (if any) of `self`.
1232 /// * if `path` has a prefix but no root, it replaces `self`.
1233 /// * if `self` has a verbatim prefix (e.g. `\\?\C:\windows`)
1234 /// and `path` is not empty, the new path is normalized: all references
1235 /// to `.` and `..` are removed.
1239 /// Pushing a relative path extends the existing path:
1242 /// use std::path::PathBuf;
1244 /// let mut path = PathBuf::from("/tmp");
1245 /// path.push("file.bk");
1246 /// assert_eq!(path, PathBuf::from("/tmp/file.bk"));
1249 /// Pushing an absolute path replaces the existing path:
1252 /// use std::path::PathBuf;
1254 /// let mut path = PathBuf::from("/tmp");
1255 /// path.push("/etc");
1256 /// assert_eq!(path, PathBuf::from("/etc"));
1258 #[stable(feature = "rust1", since = "1.0.0")]
1259 pub fn push
<P
: AsRef
<Path
>>(&mut self, path
: P
) {
1260 self._push(path
.as_ref())
1263 fn _push(&mut self, path
: &Path
) {
1264 // in general, a separator is needed if the rightmost byte is not a separator
1265 let mut need_sep
= self.as_mut_vec().last().map(|c
| !is_sep_byte(*c
)).unwrap_or(false);
1267 // in the special case of `C:` on Windows, do *not* add a separator
1268 let comps
= self.components();
1270 if comps
.prefix_len() > 0
1271 && comps
.prefix_len() == comps
.path
.len()
1272 && comps
.prefix
.unwrap().is_drive()
1277 // absolute `path` replaces `self`
1278 if path
.is_absolute() || path
.prefix().is_some() {
1279 self.as_mut_vec().truncate(0);
1281 // verbatim paths need . and .. removed
1282 } else if comps
.prefix_verbatim() && !path
.inner
.is_empty() {
1283 let mut buf
: Vec
<_
> = comps
.collect();
1284 for c
in path
.components() {
1286 Component
::RootDir
=> {
1290 Component
::CurDir
=> (),
1291 Component
::ParentDir
=> {
1292 if let Some(Component
::Normal(_
)) = buf
.last() {
1300 let mut res
= OsString
::new();
1301 let mut need_sep
= false;
1304 if need_sep
&& c
!= Component
::RootDir
{
1305 res
.push(MAIN_SEP_STR
);
1307 res
.push(c
.as_os_str());
1309 need_sep
= match c
{
1310 Component
::RootDir
=> false,
1311 Component
::Prefix(prefix
) => {
1312 !prefix
.parsed
.is_drive() && prefix
.parsed
.len() > 0
1321 // `path` has a root but no prefix, e.g., `\windows` (Windows only)
1322 } else if path
.has_root() {
1323 let prefix_len
= self.components().prefix_remaining();
1324 self.as_mut_vec().truncate(prefix_len
);
1326 // `path` is a pure relative path
1327 } else if need_sep
{
1328 self.inner
.push(MAIN_SEP_STR
);
1331 self.inner
.push(path
);
1334 /// Truncates `self` to [`self.parent`].
1336 /// Returns `false` and does nothing if [`self.parent`] is [`None`].
1337 /// Otherwise, returns `true`.
1339 /// [`self.parent`]: Path::parent
1344 /// use std::path::{Path, PathBuf};
1346 /// let mut p = PathBuf::from("/spirited/away.rs");
1349 /// assert_eq!(Path::new("/spirited"), p);
1351 /// assert_eq!(Path::new("/"), p);
1353 #[stable(feature = "rust1", since = "1.0.0")]
1354 pub fn pop(&mut self) -> bool
{
1355 match self.parent().map(|p
| p
.as_u8_slice().len()) {
1357 self.as_mut_vec().truncate(len
);
1364 /// Updates [`self.file_name`] to `file_name`.
1366 /// If [`self.file_name`] was [`None`], this is equivalent to pushing
1369 /// Otherwise it is equivalent to calling [`pop`] and then pushing
1370 /// `file_name`. The new path will be a sibling of the original path.
1371 /// (That is, it will have the same parent.)
1373 /// [`self.file_name`]: Path::file_name
1374 /// [`pop`]: PathBuf::pop
1379 /// use std::path::PathBuf;
1381 /// let mut buf = PathBuf::from("/");
1382 /// assert!(buf.file_name() == None);
1383 /// buf.set_file_name("bar");
1384 /// assert!(buf == PathBuf::from("/bar"));
1385 /// assert!(buf.file_name().is_some());
1386 /// buf.set_file_name("baz.txt");
1387 /// assert!(buf == PathBuf::from("/baz.txt"));
1389 #[stable(feature = "rust1", since = "1.0.0")]
1390 pub fn set_file_name
<S
: AsRef
<OsStr
>>(&mut self, file_name
: S
) {
1391 self._set_file_name(file_name
.as_ref())
1394 fn _set_file_name(&mut self, file_name
: &OsStr
) {
1395 if self.file_name().is_some() {
1396 let popped
= self.pop();
1397 debug_assert
!(popped
);
1399 self.push(file_name
);
1402 /// Updates [`self.extension`] to `extension`.
1404 /// Returns `false` and does nothing if [`self.file_name`] is [`None`],
1405 /// returns `true` and updates the extension otherwise.
1407 /// If [`self.extension`] is [`None`], the extension is added; otherwise
1410 /// [`self.file_name`]: Path::file_name
1411 /// [`self.extension`]: Path::extension
1416 /// use std::path::{Path, PathBuf};
1418 /// let mut p = PathBuf::from("/feel/the");
1420 /// p.set_extension("force");
1421 /// assert_eq!(Path::new("/feel/the.force"), p.as_path());
1423 /// p.set_extension("dark_side");
1424 /// assert_eq!(Path::new("/feel/the.dark_side"), p.as_path());
1426 #[stable(feature = "rust1", since = "1.0.0")]
1427 pub fn set_extension
<S
: AsRef
<OsStr
>>(&mut self, extension
: S
) -> bool
{
1428 self._set_extension(extension
.as_ref())
1431 fn _set_extension(&mut self, extension
: &OsStr
) -> bool
{
1432 let file_stem
= match self.file_stem() {
1433 None
=> return false,
1434 Some(f
) => os_str_as_u8_slice(f
),
1437 // truncate until right after the file stem
1438 let end_file_stem
= file_stem
[file_stem
.len()..].as_ptr() as usize;
1439 let start
= os_str_as_u8_slice(&self.inner
).as_ptr() as usize;
1440 let v
= self.as_mut_vec();
1441 v
.truncate(end_file_stem
.wrapping_sub(start
));
1443 // add the new extension, if any
1444 let new
= os_str_as_u8_slice(extension
);
1445 if !new
.is_empty() {
1446 v
.reserve_exact(new
.len() + 1);
1448 v
.extend_from_slice(new
);
1454 /// Consumes the `PathBuf`, yielding its internal [`OsString`] storage.
1459 /// use std::path::PathBuf;
1461 /// let p = PathBuf::from("/the/head");
1462 /// let os_str = p.into_os_string();
1464 #[stable(feature = "rust1", since = "1.0.0")]
1465 #[must_use = "`self` will be dropped if the result is not used"]
1467 pub fn into_os_string(self) -> OsString
{
1471 /// Converts this `PathBuf` into a [boxed](Box) [`Path`].
1472 #[stable(feature = "into_boxed_path", since = "1.20.0")]
1473 #[must_use = "`self` will be dropped if the result is not used"]
1475 pub fn into_boxed_path(self) -> Box
<Path
> {
1476 let rw
= Box
::into_raw(self.inner
.into_boxed_os_str()) as *mut Path
;
1477 unsafe { Box::from_raw(rw) }
1480 /// Invokes [`capacity`] on the underlying instance of [`OsString`].
1482 /// [`capacity`]: OsString::capacity
1483 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1486 pub fn capacity(&self) -> usize {
1487 self.inner
.capacity()
1490 /// Invokes [`clear`] on the underlying instance of [`OsString`].
1492 /// [`clear`]: OsString::clear
1493 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1495 pub fn clear(&mut self) {
1499 /// Invokes [`reserve`] on the underlying instance of [`OsString`].
1501 /// [`reserve`]: OsString::reserve
1502 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1504 pub fn reserve(&mut self, additional
: usize) {
1505 self.inner
.reserve(additional
)
1508 /// Invokes [`reserve_exact`] on the underlying instance of [`OsString`].
1510 /// [`reserve_exact`]: OsString::reserve_exact
1511 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1513 pub fn reserve_exact(&mut self, additional
: usize) {
1514 self.inner
.reserve_exact(additional
)
1517 /// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`].
1519 /// [`shrink_to_fit`]: OsString::shrink_to_fit
1520 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1522 pub fn shrink_to_fit(&mut self) {
1523 self.inner
.shrink_to_fit()
1526 /// Invokes [`shrink_to`] on the underlying instance of [`OsString`].
1528 /// [`shrink_to`]: OsString::shrink_to
1529 #[stable(feature = "shrink_to", since = "1.56.0")]
1531 pub fn shrink_to(&mut self, min_capacity
: usize) {
1532 self.inner
.shrink_to(min_capacity
)
1536 #[stable(feature = "rust1", since = "1.0.0")]
1537 impl Clone
for PathBuf
{
1539 fn clone(&self) -> Self {
1540 PathBuf { inner: self.inner.clone() }
1544 fn clone_from(&mut self, source
: &Self) {
1545 self.inner
.clone_from(&source
.inner
)
1549 #[stable(feature = "box_from_path", since = "1.17.0")]
1550 impl From
<&Path
> for Box
<Path
> {
1551 /// Creates a boxed [`Path`] from a reference.
1553 /// This will allocate and clone `path` to it.
1554 fn from(path
: &Path
) -> Box
<Path
> {
1555 let boxed
: Box
<OsStr
> = path
.inner
.into();
1556 let rw
= Box
::into_raw(boxed
) as *mut Path
;
1557 unsafe { Box::from_raw(rw) }
1561 #[stable(feature = "box_from_cow", since = "1.45.0")]
1562 impl From
<Cow
<'_
, Path
>> for Box
<Path
> {
1563 /// Creates a boxed [`Path`] from a clone-on-write pointer.
1565 /// Converting from a `Cow::Owned` does not clone or allocate.
1567 fn from(cow
: Cow
<'_
, Path
>) -> Box
<Path
> {
1569 Cow
::Borrowed(path
) => Box
::from(path
),
1570 Cow
::Owned(path
) => Box
::from(path
),
1575 #[stable(feature = "path_buf_from_box", since = "1.18.0")]
1576 impl From
<Box
<Path
>> for PathBuf
{
1577 /// Converts a `Box<Path>` into a `PathBuf`
1579 /// This conversion does not allocate or copy memory.
1581 fn from(boxed
: Box
<Path
>) -> PathBuf
{
1582 boxed
.into_path_buf()
1586 #[stable(feature = "box_from_path_buf", since = "1.20.0")]
1587 impl From
<PathBuf
> for Box
<Path
> {
1588 /// Converts a `PathBuf` into a `Box<Path>`
1590 /// This conversion currently should not allocate memory,
1591 /// but this behavior is not guaranteed on all platforms or in all future versions.
1593 fn from(p
: PathBuf
) -> Box
<Path
> {
1598 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
1599 impl Clone
for Box
<Path
> {
1601 fn clone(&self) -> Self {
1602 self.to_path_buf().into_boxed_path()
1606 #[stable(feature = "rust1", since = "1.0.0")]
1607 impl<T
: ?Sized
+ AsRef
<OsStr
>> From
<&T
> for PathBuf
{
1608 /// Converts a borrowed `OsStr` to a `PathBuf`.
1610 /// Allocates a [`PathBuf`] and copies the data into it.
1612 fn from(s
: &T
) -> PathBuf
{
1613 PathBuf
::from(s
.as_ref().to_os_string())
1617 #[stable(feature = "rust1", since = "1.0.0")]
1618 impl From
<OsString
> for PathBuf
{
1619 /// Converts an [`OsString`] into a [`PathBuf`]
1621 /// This conversion does not allocate or copy memory.
1623 fn from(s
: OsString
) -> PathBuf
{
1624 PathBuf { inner: s }
1628 #[stable(feature = "from_path_buf_for_os_string", since = "1.14.0")]
1629 impl From
<PathBuf
> for OsString
{
1630 /// Converts a [`PathBuf`] into an [`OsString`]
1632 /// This conversion does not allocate or copy memory.
1634 fn from(path_buf
: PathBuf
) -> OsString
{
1639 #[stable(feature = "rust1", since = "1.0.0")]
1640 impl From
<String
> for PathBuf
{
1641 /// Converts a [`String`] into a [`PathBuf`]
1643 /// This conversion does not allocate or copy memory.
1645 fn from(s
: String
) -> PathBuf
{
1646 PathBuf
::from(OsString
::from(s
))
1650 #[stable(feature = "path_from_str", since = "1.32.0")]
1651 impl FromStr
for PathBuf
{
1652 type Err
= core
::convert
::Infallible
;
1655 fn from_str(s
: &str) -> Result
<Self, Self::Err
> {
1656 Ok(PathBuf
::from(s
))
1660 #[stable(feature = "rust1", since = "1.0.0")]
1661 impl<P
: AsRef
<Path
>> iter
::FromIterator
<P
> for PathBuf
{
1662 fn from_iter
<I
: IntoIterator
<Item
= P
>>(iter
: I
) -> PathBuf
{
1663 let mut buf
= PathBuf
::new();
1669 #[stable(feature = "rust1", since = "1.0.0")]
1670 impl<P
: AsRef
<Path
>> iter
::Extend
<P
> for PathBuf
{
1671 fn extend
<I
: IntoIterator
<Item
= P
>>(&mut self, iter
: I
) {
1672 iter
.into_iter().for_each(move |p
| self.push(p
.as_ref()));
1676 fn extend_one(&mut self, p
: P
) {
1677 self.push(p
.as_ref());
1681 #[stable(feature = "rust1", since = "1.0.0")]
1682 impl fmt
::Debug
for PathBuf
{
1683 fn fmt(&self, formatter
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
1684 fmt
::Debug
::fmt(&**self, formatter
)
1688 #[stable(feature = "rust1", since = "1.0.0")]
1689 impl ops
::Deref
for PathBuf
{
1692 fn deref(&self) -> &Path
{
1693 Path
::new(&self.inner
)
1697 #[stable(feature = "rust1", since = "1.0.0")]
1698 impl Borrow
<Path
> for PathBuf
{
1700 fn borrow(&self) -> &Path
{
1705 #[stable(feature = "default_for_pathbuf", since = "1.17.0")]
1706 impl Default
for PathBuf
{
1708 fn default() -> Self {
1713 #[stable(feature = "cow_from_path", since = "1.6.0")]
1714 impl<'a
> From
<&'a Path
> for Cow
<'a
, Path
> {
1715 /// Creates a clone-on-write pointer from a reference to
1718 /// This conversion does not clone or allocate.
1720 fn from(s
: &'a Path
) -> Cow
<'a
, Path
> {
1725 #[stable(feature = "cow_from_path", since = "1.6.0")]
1726 impl<'a
> From
<PathBuf
> for Cow
<'a
, Path
> {
1727 /// Creates a clone-on-write pointer from an owned
1728 /// instance of [`PathBuf`].
1730 /// This conversion does not clone or allocate.
1732 fn from(s
: PathBuf
) -> Cow
<'a
, Path
> {
1737 #[stable(feature = "cow_from_pathbuf_ref", since = "1.28.0")]
1738 impl<'a
> From
<&'a PathBuf
> for Cow
<'a
, Path
> {
1739 /// Creates a clone-on-write pointer from a reference to
1742 /// This conversion does not clone or allocate.
1744 fn from(p
: &'a PathBuf
) -> Cow
<'a
, Path
> {
1745 Cow
::Borrowed(p
.as_path())
1749 #[stable(feature = "pathbuf_from_cow_path", since = "1.28.0")]
1750 impl<'a
> From
<Cow
<'a
, Path
>> for PathBuf
{
1751 /// Converts a clone-on-write pointer to an owned path.
1753 /// Converting from a `Cow::Owned` does not clone or allocate.
1755 fn from(p
: Cow
<'a
, Path
>) -> Self {
1760 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
1761 impl From
<PathBuf
> for Arc
<Path
> {
1762 /// Converts a [`PathBuf`] into an [`Arc`] by moving the [`PathBuf`] data into a new [`Arc`] buffer.
1764 fn from(s
: PathBuf
) -> Arc
<Path
> {
1765 let arc
: Arc
<OsStr
> = Arc
::from(s
.into_os_string());
1766 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) }
1770 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
1771 impl From
<&Path
> for Arc
<Path
> {
1772 /// Converts a [`Path`] into an [`Arc`] by copying the [`Path`] data into a new [`Arc`] buffer.
1774 fn from(s
: &Path
) -> Arc
<Path
> {
1775 let arc
: Arc
<OsStr
> = Arc
::from(s
.as_os_str());
1776 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) }
1780 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
1781 impl From
<PathBuf
> for Rc
<Path
> {
1782 /// Converts a [`PathBuf`] into an [`Rc`] by moving the [`PathBuf`] data into a new `Rc` buffer.
1784 fn from(s
: PathBuf
) -> Rc
<Path
> {
1785 let rc
: Rc
<OsStr
> = Rc
::from(s
.into_os_string());
1786 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) }
1790 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
1791 impl From
<&Path
> for Rc
<Path
> {
1792 /// Converts a [`Path`] into an [`Rc`] by copying the [`Path`] data into a new `Rc` buffer.
1794 fn from(s
: &Path
) -> Rc
<Path
> {
1795 let rc
: Rc
<OsStr
> = Rc
::from(s
.as_os_str());
1796 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) }
1800 #[stable(feature = "rust1", since = "1.0.0")]
1801 impl ToOwned
for Path
{
1802 type Owned
= PathBuf
;
1804 fn to_owned(&self) -> PathBuf
{
1808 fn clone_into(&self, target
: &mut PathBuf
) {
1809 self.inner
.clone_into(&mut target
.inner
);
1813 #[stable(feature = "rust1", since = "1.0.0")]
1814 impl cmp
::PartialEq
for PathBuf
{
1816 fn eq(&self, other
: &PathBuf
) -> bool
{
1817 self.components() == other
.components()
1821 #[stable(feature = "rust1", since = "1.0.0")]
1822 impl Hash
for PathBuf
{
1823 fn hash
<H
: Hasher
>(&self, h
: &mut H
) {
1824 self.as_path().hash(h
)
1828 #[stable(feature = "rust1", since = "1.0.0")]
1829 impl cmp
::Eq
for PathBuf {}
1831 #[stable(feature = "rust1", since = "1.0.0")]
1832 impl cmp
::PartialOrd
for PathBuf
{
1834 fn partial_cmp(&self, other
: &PathBuf
) -> Option
<cmp
::Ordering
> {
1835 Some(compare_components(self.components(), other
.components()))
1839 #[stable(feature = "rust1", since = "1.0.0")]
1840 impl cmp
::Ord
for PathBuf
{
1842 fn cmp(&self, other
: &PathBuf
) -> cmp
::Ordering
{
1843 compare_components(self.components(), other
.components())
1847 #[stable(feature = "rust1", since = "1.0.0")]
1848 impl AsRef
<OsStr
> for PathBuf
{
1850 fn as_ref(&self) -> &OsStr
{
1855 /// A slice of a path (akin to [`str`]).
1857 /// This type supports a number of operations for inspecting a path, including
1858 /// breaking the path into its components (separated by `/` on Unix and by either
1859 /// `/` or `\` on Windows), extracting the file name, determining whether the path
1860 /// is absolute, and so on.
1862 /// This is an *unsized* type, meaning that it must always be used behind a
1863 /// pointer like `&` or [`Box`]. For an owned version of this type,
1864 /// see [`PathBuf`].
1866 /// More details about the overall approach can be found in
1867 /// the [module documentation](self).
1872 /// use std::path::Path;
1873 /// use std::ffi::OsStr;
1875 /// // Note: this example does work on Windows
1876 /// let path = Path::new("./foo/bar.txt");
1878 /// let parent = path.parent();
1879 /// assert_eq!(parent, Some(Path::new("./foo")));
1881 /// let file_stem = path.file_stem();
1882 /// assert_eq!(file_stem, Some(OsStr::new("bar")));
1884 /// let extension = path.extension();
1885 /// assert_eq!(extension, Some(OsStr::new("txt")));
1887 #[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
1888 #[stable(feature = "rust1", since = "1.0.0")]
1890 // `Path::new` current implementation relies
1891 // on `Path` being layout-compatible with `OsStr`.
1892 // When attribute privacy is implemented, `Path` should be annotated as `#[repr(transparent)]`.
1893 // Anyway, `Path` representation and layout are considered implementation detail, are
1894 // not documented and must not be relied upon.
1899 /// An error returned from [`Path::strip_prefix`] if the prefix was not found.
1901 /// This `struct` is created by the [`strip_prefix`] method on [`Path`].
1902 /// See its documentation for more.
1904 /// [`strip_prefix`]: Path::strip_prefix
1905 #[derive(Debug, Clone, PartialEq, Eq)]
1906 #[stable(since = "1.7.0", feature = "strip_prefix")]
1907 pub struct StripPrefixError(());
1910 // The following (private!) function allows construction of a path from a u8
1911 // slice, which is only safe when it is known to follow the OsStr encoding.
1912 unsafe fn from_u8_slice(s
: &[u8]) -> &Path
{
1913 unsafe { Path::new(u8_slice_as_os_str(s)) }
1915 // The following (private!) function reveals the byte encoding used for OsStr.
1916 fn as_u8_slice(&self) -> &[u8] {
1917 os_str_as_u8_slice(&self.inner
)
1920 /// Directly wraps a string slice as a `Path` slice.
1922 /// This is a cost-free conversion.
1927 /// use std::path::Path;
1929 /// Path::new("foo.txt");
1932 /// You can create `Path`s from `String`s, or even other `Path`s:
1935 /// use std::path::Path;
1937 /// let string = String::from("foo.txt");
1938 /// let from_string = Path::new(&string);
1939 /// let from_path = Path::new(&from_string);
1940 /// assert_eq!(from_string, from_path);
1942 #[stable(feature = "rust1", since = "1.0.0")]
1943 pub fn new
<S
: AsRef
<OsStr
> + ?Sized
>(s
: &S
) -> &Path
{
1944 unsafe { &*(s.as_ref() as *const OsStr as *const Path) }
1947 /// Yields the underlying [`OsStr`] slice.
1952 /// use std::path::Path;
1954 /// let os_str = Path::new("foo.txt").as_os_str();
1955 /// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt"));
1957 #[stable(feature = "rust1", since = "1.0.0")]
1960 pub fn as_os_str(&self) -> &OsStr
{
1964 /// Yields a [`&str`] slice if the `Path` is valid unicode.
1966 /// This conversion may entail doing a check for UTF-8 validity.
1967 /// Note that validation is performed because non-UTF-8 strings are
1968 /// perfectly valid for some OS.
1975 /// use std::path::Path;
1977 /// let path = Path::new("foo.txt");
1978 /// assert_eq!(path.to_str(), Some("foo.txt"));
1980 #[stable(feature = "rust1", since = "1.0.0")]
1981 #[must_use = "this returns the result of the operation, \
1982 without modifying the original"]
1984 pub fn to_str(&self) -> Option
<&str> {
1988 /// Converts a `Path` to a [`Cow<str>`].
1990 /// Any non-Unicode sequences are replaced with
1991 /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
1993 /// [U+FFFD]: super::char::REPLACEMENT_CHARACTER
1997 /// Calling `to_string_lossy` on a `Path` with valid unicode:
2000 /// use std::path::Path;
2002 /// let path = Path::new("foo.txt");
2003 /// assert_eq!(path.to_string_lossy(), "foo.txt");
2006 /// Had `path` contained invalid unicode, the `to_string_lossy` call might
2007 /// have returned `"fo�.txt"`.
2008 #[stable(feature = "rust1", since = "1.0.0")]
2009 #[must_use = "this returns the result of the operation, \
2010 without modifying the original"]
2012 pub fn to_string_lossy(&self) -> Cow
<'_
, str> {
2013 self.inner
.to_string_lossy()
2016 /// Converts a `Path` to an owned [`PathBuf`].
2021 /// use std::path::Path;
2023 /// let path_buf = Path::new("foo.txt").to_path_buf();
2024 /// assert_eq!(path_buf, std::path::PathBuf::from("foo.txt"));
2026 #[rustc_conversion_suggestion]
2027 #[must_use = "this returns the result of the operation, \
2028 without modifying the original"]
2029 #[stable(feature = "rust1", since = "1.0.0")]
2030 pub fn to_path_buf(&self) -> PathBuf
{
2031 PathBuf
::from(self.inner
.to_os_string())
2034 /// Returns `true` if the `Path` is absolute, i.e., if it is independent of
2035 /// the current directory.
2037 /// * On Unix, a path is absolute if it starts with the root, so
2038 /// `is_absolute` and [`has_root`] are equivalent.
2040 /// * On Windows, a path is absolute if it has a prefix and starts with the
2041 /// root: `c:\windows` is absolute, while `c:temp` and `\temp` are not.
2046 /// use std::path::Path;
2048 /// assert!(!Path::new("foo.txt").is_absolute());
2051 /// [`has_root`]: Path::has_root
2052 #[stable(feature = "rust1", since = "1.0.0")]
2054 #[allow(deprecated)]
2055 pub fn is_absolute(&self) -> bool
{
2056 if cfg
!(target_os
= "redox") {
2057 // FIXME: Allow Redox prefixes
2058 self.has_root() || has_redox_scheme(self.as_u8_slice())
2060 self.has_root() && (cfg
!(any(unix
, target_os
= "wasi")) || self.prefix().is_some())
2064 /// Returns `true` if the `Path` is relative, i.e., not absolute.
2066 /// See [`is_absolute`]'s documentation for more details.
2071 /// use std::path::Path;
2073 /// assert!(Path::new("foo.txt").is_relative());
2076 /// [`is_absolute`]: Path::is_absolute
2077 #[stable(feature = "rust1", since = "1.0.0")]
2080 pub fn is_relative(&self) -> bool
{
2084 fn prefix(&self) -> Option
<Prefix
<'_
>> {
2085 self.components().prefix
2088 /// Returns `true` if the `Path` has a root.
2090 /// * On Unix, a path has a root if it begins with `/`.
2092 /// * On Windows, a path has a root if it:
2093 /// * has no prefix and begins with a separator, e.g., `\windows`
2094 /// * has a prefix followed by a separator, e.g., `c:\windows` but not `c:windows`
2095 /// * has any non-disk prefix, e.g., `\\server\share`
2100 /// use std::path::Path;
2102 /// assert!(Path::new("/etc/passwd").has_root());
2104 #[stable(feature = "rust1", since = "1.0.0")]
2107 pub fn has_root(&self) -> bool
{
2108 self.components().has_root()
2111 /// Returns the `Path` without its final component, if there is one.
2113 /// Returns [`None`] if the path terminates in a root or prefix.
2118 /// use std::path::Path;
2120 /// let path = Path::new("/foo/bar");
2121 /// let parent = path.parent().unwrap();
2122 /// assert_eq!(parent, Path::new("/foo"));
2124 /// let grand_parent = parent.parent().unwrap();
2125 /// assert_eq!(grand_parent, Path::new("/"));
2126 /// assert_eq!(grand_parent.parent(), None);
2128 #[stable(feature = "rust1", since = "1.0.0")]
2130 pub fn parent(&self) -> Option
<&Path
> {
2131 let mut comps
= self.components();
2132 let comp
= comps
.next_back();
2133 comp
.and_then(|p
| match p
{
2134 Component
::Normal(_
) | Component
::CurDir
| Component
::ParentDir
=> {
2135 Some(comps
.as_path())
2141 /// Produces an iterator over `Path` and its ancestors.
2143 /// The iterator will yield the `Path` that is returned if the [`parent`] method is used zero
2144 /// or more times. That means, the iterator will yield `&self`, `&self.parent().unwrap()`,
2145 /// `&self.parent().unwrap().parent().unwrap()` and so on. If the [`parent`] method returns
2146 /// [`None`], the iterator will do likewise. The iterator will always yield at least one value,
2152 /// use std::path::Path;
2154 /// let mut ancestors = Path::new("/foo/bar").ancestors();
2155 /// assert_eq!(ancestors.next(), Some(Path::new("/foo/bar")));
2156 /// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
2157 /// assert_eq!(ancestors.next(), Some(Path::new("/")));
2158 /// assert_eq!(ancestors.next(), None);
2160 /// let mut ancestors = Path::new("../foo/bar").ancestors();
2161 /// assert_eq!(ancestors.next(), Some(Path::new("../foo/bar")));
2162 /// assert_eq!(ancestors.next(), Some(Path::new("../foo")));
2163 /// assert_eq!(ancestors.next(), Some(Path::new("..")));
2164 /// assert_eq!(ancestors.next(), Some(Path::new("")));
2165 /// assert_eq!(ancestors.next(), None);
2168 /// [`parent`]: Path::parent
2169 #[stable(feature = "path_ancestors", since = "1.28.0")]
2171 pub fn ancestors(&self) -> Ancestors
<'_
> {
2172 Ancestors { next: Some(&self) }
2175 /// Returns the final component of the `Path`, if there is one.
2177 /// If the path is a normal file, this is the file name. If it's the path of a directory, this
2178 /// is the directory name.
2180 /// Returns [`None`] if the path terminates in `..`.
2185 /// use std::path::Path;
2186 /// use std::ffi::OsStr;
2188 /// assert_eq!(Some(OsStr::new("bin")), Path::new("/usr/bin/").file_name());
2189 /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("tmp/foo.txt").file_name());
2190 /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.").file_name());
2191 /// assert_eq!(Some(OsStr::new("foo.txt")), Path::new("foo.txt/.//").file_name());
2192 /// assert_eq!(None, Path::new("foo.txt/..").file_name());
2193 /// assert_eq!(None, Path::new("/").file_name());
2195 #[stable(feature = "rust1", since = "1.0.0")]
2197 pub fn file_name(&self) -> Option
<&OsStr
> {
2198 self.components().next_back().and_then(|p
| match p
{
2199 Component
::Normal(p
) => Some(p
),
2204 /// Returns a path that, when joined onto `base`, yields `self`.
2208 /// If `base` is not a prefix of `self` (i.e., [`starts_with`]
2209 /// returns `false`), returns [`Err`].
2211 /// [`starts_with`]: Path::starts_with
2216 /// use std::path::{Path, PathBuf};
2218 /// let path = Path::new("/test/haha/foo.txt");
2220 /// assert_eq!(path.strip_prefix("/"), Ok(Path::new("test/haha/foo.txt")));
2221 /// assert_eq!(path.strip_prefix("/test"), Ok(Path::new("haha/foo.txt")));
2222 /// assert_eq!(path.strip_prefix("/test/"), Ok(Path::new("haha/foo.txt")));
2223 /// assert_eq!(path.strip_prefix("/test/haha/foo.txt"), Ok(Path::new("")));
2224 /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
2226 /// assert!(path.strip_prefix("test").is_err());
2227 /// assert!(path.strip_prefix("/haha").is_err());
2229 /// let prefix = PathBuf::from("/test/");
2230 /// assert_eq!(path.strip_prefix(prefix), Ok(Path::new("haha/foo.txt")));
2232 #[stable(since = "1.7.0", feature = "path_strip_prefix")]
2233 pub fn strip_prefix
<P
>(&self, base
: P
) -> Result
<&Path
, StripPrefixError
>
2237 self._strip_prefix(base
.as_ref())
2240 fn _strip_prefix(&self, base
: &Path
) -> Result
<&Path
, StripPrefixError
> {
2241 iter_after(self.components(), base
.components())
2242 .map(|c
| c
.as_path())
2243 .ok_or(StripPrefixError(()))
2246 /// Determines whether `base` is a prefix of `self`.
2248 /// Only considers whole path components to match.
2253 /// use std::path::Path;
2255 /// let path = Path::new("/etc/passwd");
2257 /// assert!(path.starts_with("/etc"));
2258 /// assert!(path.starts_with("/etc/"));
2259 /// assert!(path.starts_with("/etc/passwd"));
2260 /// assert!(path.starts_with("/etc/passwd/")); // extra slash is okay
2261 /// assert!(path.starts_with("/etc/passwd///")); // multiple extra slashes are okay
2263 /// assert!(!path.starts_with("/e"));
2264 /// assert!(!path.starts_with("/etc/passwd.txt"));
2266 /// assert!(!Path::new("/etc/foo.rs").starts_with("/etc/foo"));
2268 #[stable(feature = "rust1", since = "1.0.0")]
2270 pub fn starts_with
<P
: AsRef
<Path
>>(&self, base
: P
) -> bool
{
2271 self._starts_with(base
.as_ref())
2274 fn _starts_with(&self, base
: &Path
) -> bool
{
2275 iter_after(self.components(), base
.components()).is_some()
2278 /// Determines whether `child` is a suffix of `self`.
2280 /// Only considers whole path components to match.
2285 /// use std::path::Path;
2287 /// let path = Path::new("/etc/resolv.conf");
2289 /// assert!(path.ends_with("resolv.conf"));
2290 /// assert!(path.ends_with("etc/resolv.conf"));
2291 /// assert!(path.ends_with("/etc/resolv.conf"));
2293 /// assert!(!path.ends_with("/resolv.conf"));
2294 /// assert!(!path.ends_with("conf")); // use .extension() instead
2296 #[stable(feature = "rust1", since = "1.0.0")]
2298 pub fn ends_with
<P
: AsRef
<Path
>>(&self, child
: P
) -> bool
{
2299 self._ends_with(child
.as_ref())
2302 fn _ends_with(&self, child
: &Path
) -> bool
{
2303 iter_after(self.components().rev(), child
.components().rev()).is_some()
2306 /// Extracts the stem (non-extension) portion of [`self.file_name`].
2308 /// [`self.file_name`]: Path::file_name
2312 /// * [`None`], if there is no file name;
2313 /// * The entire file name if there is no embedded `.`;
2314 /// * The entire file name if the file name begins with `.` and has no other `.`s within;
2315 /// * Otherwise, the portion of the file name before the final `.`
2320 /// use std::path::Path;
2322 /// assert_eq!("foo", Path::new("foo.rs").file_stem().unwrap());
2323 /// assert_eq!("foo.tar", Path::new("foo.tar.gz").file_stem().unwrap());
2327 /// This method is similar to [`Path::file_prefix`], which extracts the portion of the file name
2328 /// before the *first* `.`
2330 /// [`Path::file_prefix`]: Path::file_prefix
2332 #[stable(feature = "rust1", since = "1.0.0")]
2334 pub fn file_stem(&self) -> Option
<&OsStr
> {
2335 self.file_name().map(rsplit_file_at_dot
).and_then(|(before
, after
)| before
.or(after
))
2338 /// Extracts the prefix of [`self.file_name`].
2342 /// * [`None`], if there is no file name;
2343 /// * The entire file name if there is no embedded `.`;
2344 /// * The portion of the file name before the first non-beginning `.`;
2345 /// * The entire file name if the file name begins with `.` and has no other `.`s within;
2346 /// * The portion of the file name before the second `.` if the file name begins with `.`
2348 /// [`self.file_name`]: Path::file_name
2353 /// # #![feature(path_file_prefix)]
2354 /// use std::path::Path;
2356 /// assert_eq!("foo", Path::new("foo.rs").file_prefix().unwrap());
2357 /// assert_eq!("foo", Path::new("foo.tar.gz").file_prefix().unwrap());
2361 /// This method is similar to [`Path::file_stem`], which extracts the portion of the file name
2362 /// before the *last* `.`
2364 /// [`Path::file_stem`]: Path::file_stem
2366 #[unstable(feature = "path_file_prefix", issue = "86319")]
2368 pub fn file_prefix(&self) -> Option
<&OsStr
> {
2369 self.file_name().map(split_file_at_dot
).and_then(|(before
, _after
)| Some(before
))
2372 /// Extracts the extension of [`self.file_name`], if possible.
2374 /// The extension is:
2376 /// * [`None`], if there is no file name;
2377 /// * [`None`], if there is no embedded `.`;
2378 /// * [`None`], if the file name begins with `.` and has no other `.`s within;
2379 /// * Otherwise, the portion of the file name after the final `.`
2381 /// [`self.file_name`]: Path::file_name
2386 /// use std::path::Path;
2388 /// assert_eq!("rs", Path::new("foo.rs").extension().unwrap());
2389 /// assert_eq!("gz", Path::new("foo.tar.gz").extension().unwrap());
2391 #[stable(feature = "rust1", since = "1.0.0")]
2393 pub fn extension(&self) -> Option
<&OsStr
> {
2394 self.file_name().map(rsplit_file_at_dot
).and_then(|(before
, after
)| before
.and(after
))
2397 /// Creates an owned [`PathBuf`] with `path` adjoined to `self`.
2399 /// See [`PathBuf::push`] for more details on what it means to adjoin a path.
2404 /// use std::path::{Path, PathBuf};
2406 /// assert_eq!(Path::new("/etc").join("passwd"), PathBuf::from("/etc/passwd"));
2408 #[stable(feature = "rust1", since = "1.0.0")]
2410 pub fn join
<P
: AsRef
<Path
>>(&self, path
: P
) -> PathBuf
{
2411 self._join(path
.as_ref())
2414 fn _join(&self, path
: &Path
) -> PathBuf
{
2415 let mut buf
= self.to_path_buf();
2420 /// Creates an owned [`PathBuf`] like `self` but with the given file name.
2422 /// See [`PathBuf::set_file_name`] for more details.
2427 /// use std::path::{Path, PathBuf};
2429 /// let path = Path::new("/tmp/foo.txt");
2430 /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt"));
2432 /// let path = Path::new("/tmp");
2433 /// assert_eq!(path.with_file_name("var"), PathBuf::from("/var"));
2435 #[stable(feature = "rust1", since = "1.0.0")]
2437 pub fn with_file_name
<S
: AsRef
<OsStr
>>(&self, file_name
: S
) -> PathBuf
{
2438 self._with_file_name(file_name
.as_ref())
2441 fn _with_file_name(&self, file_name
: &OsStr
) -> PathBuf
{
2442 let mut buf
= self.to_path_buf();
2443 buf
.set_file_name(file_name
);
2447 /// Creates an owned [`PathBuf`] like `self` but with the given extension.
2449 /// See [`PathBuf::set_extension`] for more details.
2454 /// use std::path::{Path, PathBuf};
2456 /// let path = Path::new("foo.rs");
2457 /// assert_eq!(path.with_extension("txt"), PathBuf::from("foo.txt"));
2459 /// let path = Path::new("foo.tar.gz");
2460 /// assert_eq!(path.with_extension(""), PathBuf::from("foo.tar"));
2461 /// assert_eq!(path.with_extension("xz"), PathBuf::from("foo.tar.xz"));
2462 /// assert_eq!(path.with_extension("").with_extension("txt"), PathBuf::from("foo.txt"));
2464 #[stable(feature = "rust1", since = "1.0.0")]
2465 pub fn with_extension
<S
: AsRef
<OsStr
>>(&self, extension
: S
) -> PathBuf
{
2466 self._with_extension(extension
.as_ref())
2469 fn _with_extension(&self, extension
: &OsStr
) -> PathBuf
{
2470 let mut buf
= self.to_path_buf();
2471 buf
.set_extension(extension
);
2475 /// Produces an iterator over the [`Component`]s of the path.
2477 /// When parsing the path, there is a small amount of normalization:
2479 /// * Repeated separators are ignored, so `a/b` and `a//b` both have
2480 /// `a` and `b` as components.
2482 /// * Occurrences of `.` are normalized away, except if they are at the
2483 /// beginning of the path. For example, `a/./b`, `a/b/`, `a/b/.` and
2484 /// `a/b` all have `a` and `b` as components, but `./a/b` starts with
2485 /// an additional [`CurDir`] component.
2487 /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
2489 /// Note that no other normalization takes place; in particular, `a/c`
2490 /// and `a/b/../c` are distinct, to account for the possibility that `b`
2491 /// is a symbolic link (so its parent isn't `a`).
2496 /// use std::path::{Path, Component};
2497 /// use std::ffi::OsStr;
2499 /// let mut components = Path::new("/tmp/foo.txt").components();
2501 /// assert_eq!(components.next(), Some(Component::RootDir));
2502 /// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("tmp"))));
2503 /// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("foo.txt"))));
2504 /// assert_eq!(components.next(), None)
2507 /// [`CurDir`]: Component::CurDir
2508 #[stable(feature = "rust1", since = "1.0.0")]
2509 pub fn components(&self) -> Components
<'_
> {
2510 let prefix
= parse_prefix(self.as_os_str());
2512 path
: self.as_u8_slice(),
2514 has_physical_root
: has_physical_root(self.as_u8_slice(), prefix
)
2515 || has_redox_scheme(self.as_u8_slice()),
2516 front
: State
::Prefix
,
2521 /// Produces an iterator over the path's components viewed as [`OsStr`]
2524 /// For more information about the particulars of how the path is separated
2525 /// into components, see [`components`].
2527 /// [`components`]: Path::components
2532 /// use std::path::{self, Path};
2533 /// use std::ffi::OsStr;
2535 /// let mut it = Path::new("/tmp/foo.txt").iter();
2536 /// assert_eq!(it.next(), Some(OsStr::new(&path::MAIN_SEPARATOR.to_string())));
2537 /// assert_eq!(it.next(), Some(OsStr::new("tmp")));
2538 /// assert_eq!(it.next(), Some(OsStr::new("foo.txt")));
2539 /// assert_eq!(it.next(), None)
2541 #[stable(feature = "rust1", since = "1.0.0")]
2543 pub fn iter(&self) -> Iter
<'_
> {
2544 Iter { inner: self.components() }
2547 /// Returns an object that implements [`Display`] for safely printing paths
2548 /// that may contain non-Unicode data. This may perform lossy conversion,
2549 /// depending on the platform. If you would like an implementation which
2550 /// escapes the path please use [`Debug`] instead.
2552 /// [`Display`]: fmt::Display
2557 /// use std::path::Path;
2559 /// let path = Path::new("/tmp/foo.rs");
2561 /// println!("{}", path.display());
2563 #[stable(feature = "rust1", since = "1.0.0")]
2564 #[must_use = "this does not display the path, \
2565 it returns an object that can be displayed"]
2567 pub fn display(&self) -> Display
<'_
> {
2568 Display { path: self }
2571 /// Queries the file system to get information about a file, directory, etc.
2573 /// This function will traverse symbolic links to query information about the
2574 /// destination file.
2576 /// This is an alias to [`fs::metadata`].
2581 /// use std::path::Path;
2583 /// let path = Path::new("/Minas/tirith");
2584 /// let metadata = path.metadata().expect("metadata call failed");
2585 /// println!("{:?}", metadata.file_type());
2587 #[stable(feature = "path_ext", since = "1.5.0")]
2589 pub fn metadata(&self) -> io
::Result
<fs
::Metadata
> {
2593 /// Queries the metadata about a file without following symlinks.
2595 /// This is an alias to [`fs::symlink_metadata`].
2600 /// use std::path::Path;
2602 /// let path = Path::new("/Minas/tirith");
2603 /// let metadata = path.symlink_metadata().expect("symlink_metadata call failed");
2604 /// println!("{:?}", metadata.file_type());
2606 #[stable(feature = "path_ext", since = "1.5.0")]
2608 pub fn symlink_metadata(&self) -> io
::Result
<fs
::Metadata
> {
2609 fs
::symlink_metadata(self)
2612 /// Returns the canonical, absolute form of the path with all intermediate
2613 /// components normalized and symbolic links resolved.
2615 /// This is an alias to [`fs::canonicalize`].
2620 /// use std::path::{Path, PathBuf};
2622 /// let path = Path::new("/foo/test/../test/bar.rs");
2623 /// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs"));
2625 #[stable(feature = "path_ext", since = "1.5.0")]
2627 pub fn canonicalize(&self) -> io
::Result
<PathBuf
> {
2628 fs
::canonicalize(self)
2631 /// Reads a symbolic link, returning the file that the link points to.
2633 /// This is an alias to [`fs::read_link`].
2638 /// use std::path::Path;
2640 /// let path = Path::new("/laputa/sky_castle.rs");
2641 /// let path_link = path.read_link().expect("read_link call failed");
2643 #[stable(feature = "path_ext", since = "1.5.0")]
2645 pub fn read_link(&self) -> io
::Result
<PathBuf
> {
2649 /// Returns an iterator over the entries within a directory.
2651 /// The iterator will yield instances of <code>[io::Result]<[fs::DirEntry]></code>. New
2652 /// errors may be encountered after an iterator is initially constructed.
2654 /// This is an alias to [`fs::read_dir`].
2659 /// use std::path::Path;
2661 /// let path = Path::new("/laputa");
2662 /// for entry in path.read_dir().expect("read_dir call failed") {
2663 /// if let Ok(entry) = entry {
2664 /// println!("{:?}", entry.path());
2668 #[stable(feature = "path_ext", since = "1.5.0")]
2670 pub fn read_dir(&self) -> io
::Result
<fs
::ReadDir
> {
2674 /// Returns `true` if the path points at an existing entity.
2676 /// This function will traverse symbolic links to query information about the
2677 /// destination file.
2679 /// If you cannot access the metadata of the file, e.g. because of a
2680 /// permission error or broken symbolic links, this will return `false`.
2685 /// use std::path::Path;
2686 /// assert!(!Path::new("does_not_exist.txt").exists());
2691 /// This is a convenience function that coerces errors to false. If you want to
2692 /// check errors, call [`fs::metadata`].
2693 #[stable(feature = "path_ext", since = "1.5.0")]
2696 pub fn exists(&self) -> bool
{
2697 fs
::metadata(self).is_ok()
2700 /// Returns `Ok(true)` if the path points at an existing entity.
2702 /// This function will traverse symbolic links to query information about the
2703 /// destination file. In case of broken symbolic links this will return `Ok(false)`.
2705 /// As opposed to the `exists()` method, this one doesn't silently ignore errors
2706 /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
2707 /// denied on some of the parent directories.)
2712 /// #![feature(path_try_exists)]
2714 /// use std::path::Path;
2715 /// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
2716 /// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
2718 // FIXME: stabilization should modify documentation of `exists()` to recommend this method
2720 #[unstable(feature = "path_try_exists", issue = "83186")]
2722 pub fn try_exists(&self) -> io
::Result
<bool
> {
2723 fs
::try_exists(self)
2726 /// Returns `true` if the path exists on disk and is pointing at a regular file.
2728 /// This function will traverse symbolic links to query information about the
2729 /// destination file.
2731 /// If you cannot access the metadata of the file, e.g. because of a
2732 /// permission error or broken symbolic links, this will return `false`.
2737 /// use std::path::Path;
2738 /// assert_eq!(Path::new("./is_a_directory/").is_file(), false);
2739 /// assert_eq!(Path::new("a_file.txt").is_file(), true);
2744 /// This is a convenience function that coerces errors to false. If you want to
2745 /// check errors, call [`fs::metadata`] and handle its [`Result`]. Then call
2746 /// [`fs::Metadata::is_file`] if it was [`Ok`].
2748 /// When the goal is simply to read from (or write to) the source, the most
2749 /// reliable way to test the source can be read (or written to) is to open
2750 /// it. Only using `is_file` can break workflows like `diff <( prog_a )` on
2751 /// a Unix-like system for example. See [`fs::File::open`] or
2752 /// [`fs::OpenOptions::open`] for more information.
2753 #[stable(feature = "path_ext", since = "1.5.0")]
2755 pub fn is_file(&self) -> bool
{
2756 fs
::metadata(self).map(|m
| m
.is_file()).unwrap_or(false)
2759 /// Returns `true` if the path exists on disk and is pointing at a directory.
2761 /// This function will traverse symbolic links to query information about the
2762 /// destination file.
2764 /// If you cannot access the metadata of the file, e.g. because of a
2765 /// permission error or broken symbolic links, this will return `false`.
2770 /// use std::path::Path;
2771 /// assert_eq!(Path::new("./is_a_directory/").is_dir(), true);
2772 /// assert_eq!(Path::new("a_file.txt").is_dir(), false);
2777 /// This is a convenience function that coerces errors to false. If you want to
2778 /// check errors, call [`fs::metadata`] and handle its [`Result`]. Then call
2779 /// [`fs::Metadata::is_dir`] if it was [`Ok`].
2780 #[stable(feature = "path_ext", since = "1.5.0")]
2782 pub fn is_dir(&self) -> bool
{
2783 fs
::metadata(self).map(|m
| m
.is_dir()).unwrap_or(false)
2786 /// Returns `true` if the path exists on disk and is pointing at a symbolic link.
2788 /// This function will not traverse symbolic links.
2789 /// In case of a broken symbolic link this will also return true.
2791 /// If you cannot access the directory containing the file, e.g., because of a
2792 /// permission error, this will return false.
2796 #[cfg_attr(unix, doc = "```no_run")]
2797 #[cfg_attr(not(unix), doc = "```ignore")]
2798 /// use std::path::Path;
2799 /// use std::os::unix::fs::symlink;
2801 /// let link_path = Path::new("link");
2802 /// symlink("/origin_does_not_exists/", link_path).unwrap();
2803 /// assert_eq!(link_path.is_symlink(), true);
2804 /// assert_eq!(link_path.exists(), false);
2809 /// This is a convenience function that coerces errors to false. If you want to
2810 /// check errors, call [`fs::symlink_metadata`] and handle its [`Result`]. Then call
2811 /// [`fs::Metadata::is_symlink`] if it was [`Ok`].
2813 #[stable(feature = "is_symlink", since = "1.57.0")]
2814 pub fn is_symlink(&self) -> bool
{
2815 fs
::symlink_metadata(self).map(|m
| m
.is_symlink()).unwrap_or(false)
2818 /// Converts a [`Box<Path>`](Box) into a [`PathBuf`] without copying or
2820 #[stable(feature = "into_boxed_path", since = "1.20.0")]
2821 #[must_use = "`self` will be dropped if the result is not used"]
2822 pub fn into_path_buf(self: Box
<Path
>) -> PathBuf
{
2823 let rw
= Box
::into_raw(self) as *mut OsStr
;
2824 let inner
= unsafe { Box::from_raw(rw) }
;
2825 PathBuf { inner: OsString::from(inner) }
2829 #[stable(feature = "rust1", since = "1.0.0")]
2830 impl AsRef
<OsStr
> for Path
{
2832 fn as_ref(&self) -> &OsStr
{
2837 #[stable(feature = "rust1", since = "1.0.0")]
2838 impl fmt
::Debug
for Path
{
2839 fn fmt(&self, formatter
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
2840 fmt
::Debug
::fmt(&self.inner
, formatter
)
2844 /// Helper struct for safely printing paths with [`format!`] and `{}`.
2846 /// A [`Path`] might contain non-Unicode data. This `struct` implements the
2847 /// [`Display`] trait in a way that mitigates that. It is created by the
2848 /// [`display`](Path::display) method on [`Path`]. This may perform lossy
2849 /// conversion, depending on the platform. If you would like an implementation
2850 /// which escapes the path please use [`Debug`] instead.
2855 /// use std::path::Path;
2857 /// let path = Path::new("/tmp/foo.rs");
2859 /// println!("{}", path.display());
2862 /// [`Display`]: fmt::Display
2863 /// [`format!`]: crate::format
2864 #[stable(feature = "rust1", since = "1.0.0")]
2865 pub struct Display
<'a
> {
2869 #[stable(feature = "rust1", since = "1.0.0")]
2870 impl fmt
::Debug
for Display
<'_
> {
2871 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
2872 fmt
::Debug
::fmt(&self.path
, f
)
2876 #[stable(feature = "rust1", since = "1.0.0")]
2877 impl fmt
::Display
for Display
<'_
> {
2878 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
2879 self.path
.inner
.display(f
)
2883 #[stable(feature = "rust1", since = "1.0.0")]
2884 impl cmp
::PartialEq
for Path
{
2886 fn eq(&self, other
: &Path
) -> bool
{
2887 self.components() == other
.components()
2891 #[stable(feature = "rust1", since = "1.0.0")]
2892 impl Hash
for Path
{
2893 fn hash
<H
: Hasher
>(&self, h
: &mut H
) {
2894 let bytes
= self.as_u8_slice();
2895 let prefix_len
= match parse_prefix(&self.inner
) {
2902 let bytes
= &bytes
[prefix_len
..];
2904 let mut component_start
= 0;
2905 let mut bytes_hashed
= 0;
2907 for i
in 0..bytes
.len() {
2908 if is_sep_byte(bytes
[i
]) {
2909 if i
> component_start
{
2910 let to_hash
= &bytes
[component_start
..i
];
2912 bytes_hashed
+= to_hash
.len();
2915 // skip over separator and optionally a following CurDir item
2916 // since components() would normalize these away
2917 component_start
= i
+ match bytes
[i
..] {
2918 [_
, b'
.'
, b'
/'
, ..] | [_
, b'
.'
] => 2,
2924 if component_start
< bytes
.len() {
2925 let to_hash
= &bytes
[component_start
..];
2927 bytes_hashed
+= to_hash
.len();
2930 h
.write_usize(bytes_hashed
);
2934 #[stable(feature = "rust1", since = "1.0.0")]
2935 impl cmp
::Eq
for Path {}
2937 #[stable(feature = "rust1", since = "1.0.0")]
2938 impl cmp
::PartialOrd
for Path
{
2940 fn partial_cmp(&self, other
: &Path
) -> Option
<cmp
::Ordering
> {
2941 Some(compare_components(self.components(), other
.components()))
2945 #[stable(feature = "rust1", since = "1.0.0")]
2946 impl cmp
::Ord
for Path
{
2948 fn cmp(&self, other
: &Path
) -> cmp
::Ordering
{
2949 compare_components(self.components(), other
.components())
2953 #[stable(feature = "rust1", since = "1.0.0")]
2954 impl AsRef
<Path
> for Path
{
2956 fn as_ref(&self) -> &Path
{
2961 #[stable(feature = "rust1", since = "1.0.0")]
2962 impl AsRef
<Path
> for OsStr
{
2964 fn as_ref(&self) -> &Path
{
2969 #[stable(feature = "cow_os_str_as_ref_path", since = "1.8.0")]
2970 impl AsRef
<Path
> for Cow
<'_
, OsStr
> {
2972 fn as_ref(&self) -> &Path
{
2977 #[stable(feature = "rust1", since = "1.0.0")]
2978 impl AsRef
<Path
> for OsString
{
2980 fn as_ref(&self) -> &Path
{
2985 #[stable(feature = "rust1", since = "1.0.0")]
2986 impl AsRef
<Path
> for str {
2988 fn as_ref(&self) -> &Path
{
2993 #[stable(feature = "rust1", since = "1.0.0")]
2994 impl AsRef
<Path
> for String
{
2996 fn as_ref(&self) -> &Path
{
3001 #[stable(feature = "rust1", since = "1.0.0")]
3002 impl AsRef
<Path
> for PathBuf
{
3004 fn as_ref(&self) -> &Path
{
3009 #[stable(feature = "path_into_iter", since = "1.6.0")]
3010 impl<'a
> IntoIterator
for &'a PathBuf
{
3011 type Item
= &'a OsStr
;
3012 type IntoIter
= Iter
<'a
>;
3014 fn into_iter(self) -> Iter
<'a
> {
3019 #[stable(feature = "path_into_iter", since = "1.6.0")]
3020 impl<'a
> IntoIterator
for &'a Path
{
3021 type Item
= &'a OsStr
;
3022 type IntoIter
= Iter
<'a
>;
3024 fn into_iter(self) -> Iter
<'a
> {
3029 macro_rules
! impl_cmp
{
3030 ($lhs
:ty
, $rhs
: ty
) => {
3031 #[stable(feature = "partialeq_path", since = "1.6.0")]
3032 impl<'a
, 'b
> PartialEq
<$rhs
> for $lhs
{
3034 fn eq(&self, other
: &$rhs
) -> bool
{
3035 <Path
as PartialEq
>::eq(self, other
)
3039 #[stable(feature = "partialeq_path", since = "1.6.0")]
3040 impl<'a
, 'b
> PartialEq
<$lhs
> for $rhs
{
3042 fn eq(&self, other
: &$lhs
) -> bool
{
3043 <Path
as PartialEq
>::eq(self, other
)
3047 #[stable(feature = "cmp_path", since = "1.8.0")]
3048 impl<'a
, 'b
> PartialOrd
<$rhs
> for $lhs
{
3050 fn partial_cmp(&self, other
: &$rhs
) -> Option
<cmp
::Ordering
> {
3051 <Path
as PartialOrd
>::partial_cmp(self, other
)
3055 #[stable(feature = "cmp_path", since = "1.8.0")]
3056 impl<'a
, 'b
> PartialOrd
<$lhs
> for $rhs
{
3058 fn partial_cmp(&self, other
: &$lhs
) -> Option
<cmp
::Ordering
> {
3059 <Path
as PartialOrd
>::partial_cmp(self, other
)
3065 impl_cmp
!(PathBuf
, Path
);
3066 impl_cmp
!(PathBuf
, &'a Path
);
3067 impl_cmp
!(Cow
<'a
, Path
>, Path
);
3068 impl_cmp
!(Cow
<'a
, Path
>, &'b Path
);
3069 impl_cmp
!(Cow
<'a
, Path
>, PathBuf
);
3071 macro_rules
! impl_cmp_os_str
{
3072 ($lhs
:ty
, $rhs
: ty
) => {
3073 #[stable(feature = "cmp_path", since = "1.8.0")]
3074 impl<'a
, 'b
> PartialEq
<$rhs
> for $lhs
{
3076 fn eq(&self, other
: &$rhs
) -> bool
{
3077 <Path
as PartialEq
>::eq(self, other
.as_ref())
3081 #[stable(feature = "cmp_path", since = "1.8.0")]
3082 impl<'a
, 'b
> PartialEq
<$lhs
> for $rhs
{
3084 fn eq(&self, other
: &$lhs
) -> bool
{
3085 <Path
as PartialEq
>::eq(self.as_ref(), other
)
3089 #[stable(feature = "cmp_path", since = "1.8.0")]
3090 impl<'a
, 'b
> PartialOrd
<$rhs
> for $lhs
{
3092 fn partial_cmp(&self, other
: &$rhs
) -> Option
<cmp
::Ordering
> {
3093 <Path
as PartialOrd
>::partial_cmp(self, other
.as_ref())
3097 #[stable(feature = "cmp_path", since = "1.8.0")]
3098 impl<'a
, 'b
> PartialOrd
<$lhs
> for $rhs
{
3100 fn partial_cmp(&self, other
: &$lhs
) -> Option
<cmp
::Ordering
> {
3101 <Path
as PartialOrd
>::partial_cmp(self.as_ref(), other
)
3107 impl_cmp_os_str
!(PathBuf
, OsStr
);
3108 impl_cmp_os_str
!(PathBuf
, &'a OsStr
);
3109 impl_cmp_os_str
!(PathBuf
, Cow
<'a
, OsStr
>);
3110 impl_cmp_os_str
!(PathBuf
, OsString
);
3111 impl_cmp_os_str
!(Path
, OsStr
);
3112 impl_cmp_os_str
!(Path
, &'a OsStr
);
3113 impl_cmp_os_str
!(Path
, Cow
<'a
, OsStr
>);
3114 impl_cmp_os_str
!(Path
, OsString
);
3115 impl_cmp_os_str
!(&'a Path
, OsStr
);
3116 impl_cmp_os_str
!(&'a Path
, Cow
<'b
, OsStr
>);
3117 impl_cmp_os_str
!(&'a Path
, OsString
);
3118 impl_cmp_os_str
!(Cow
<'a
, Path
>, OsStr
);
3119 impl_cmp_os_str
!(Cow
<'a
, Path
>, &'b OsStr
);
3120 impl_cmp_os_str
!(Cow
<'a
, Path
>, OsString
);
3122 #[stable(since = "1.7.0", feature = "strip_prefix")]
3123 impl fmt
::Display
for StripPrefixError
{
3124 #[allow(deprecated, deprecated_in_future)]
3125 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
3126 self.description().fmt(f
)
3130 #[stable(since = "1.7.0", feature = "strip_prefix")]
3131 impl Error
for StripPrefixError
{
3132 #[allow(deprecated)]
3133 fn description(&self) -> &str {