]> git.proxmox.com Git - rustc.git/blob - library/std/src/path.rs
New upstream version 1.58.1+dfsg1
[rustc.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 //! ## Simple usage
16 //!
17 //! Path manipulation includes both parsing components from slices and building
18 //! new owned paths.
19 //!
20 //! To parse a path, you can create a [`Path`] slice from a [`str`]
21 //! slice and start asking questions:
22 //!
23 //! ```
24 //! use std::path::Path;
25 //! use std::ffi::OsStr;
26 //!
27 //! let path = Path::new("/tmp/foo/bar.txt");
28 //!
29 //! let parent = path.parent();
30 //! assert_eq!(parent, Some(Path::new("/tmp/foo")));
31 //!
32 //! let file_stem = path.file_stem();
33 //! assert_eq!(file_stem, Some(OsStr::new("bar")));
34 //!
35 //! let extension = path.extension();
36 //! assert_eq!(extension, Some(OsStr::new("txt")));
37 //! ```
38 //!
39 //! To build or modify paths, use [`PathBuf`]:
40 //!
41 //! ```
42 //! use std::path::PathBuf;
43 //!
44 //! // This way works...
45 //! let mut path = PathBuf::from("c:\\");
46 //!
47 //! path.push("windows");
48 //! path.push("system32");
49 //!
50 //! path.set_extension("dll");
51 //!
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();
55 //! ```
56 //!
57 //! [`components`]: Path::components
58 //! [`push`]: PathBuf::push
59
60 #![stable(feature = "rust1", since = "1.0.0")]
61 #![deny(unsafe_op_in_unsafe_fn)]
62
63 #[cfg(test)]
64 mod tests;
65
66 use crate::borrow::{Borrow, Cow};
67 use crate::cmp;
68 use crate::error::Error;
69 use crate::fmt;
70 use crate::fs;
71 use crate::hash::{Hash, Hasher};
72 use crate::io;
73 use crate::iter::{self, FusedIterator};
74 use crate::ops::{self, Deref};
75 use crate::rc::Rc;
76 use crate::str::FromStr;
77 use crate::sync::Arc;
78
79 use crate::ffi::{OsStr, OsString};
80
81 use crate::sys::path::{is_sep_byte, is_verbatim_sep, parse_prefix, MAIN_SEP_STR};
82
83 ////////////////////////////////////////////////////////////////////////////////
84 // GENERAL NOTES
85 ////////////////////////////////////////////////////////////////////////////////
86 //
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
91 // available.
92
93 ////////////////////////////////////////////////////////////////////////////////
94 // Windows Prefixes
95 ////////////////////////////////////////////////////////////////////////////////
96
97 /// Windows path prefixes, e.g., `C:` or `\\server\share`.
98 ///
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.
104 ///
105 /// # Examples
106 ///
107 /// ```
108 /// use std::path::{Component, Path, Prefix};
109 /// use std::path::Prefix::*;
110 /// use std::ffi::OsStr;
111 ///
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(),
116 /// _ => panic!(),
117 /// }
118 /// }
119 ///
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"));
131 /// # }
132 /// ```
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`.
137 ///
138 /// Verbatim prefixes consist of `\\?\` immediately followed by the given
139 /// component.
140 #[stable(feature = "rust1", since = "1.0.0")]
141 Verbatim(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
142
143 /// Verbatim prefix using Windows' _**U**niform **N**aming **C**onvention_,
144 /// e.g., `\\?\UNC\server\share`.
145 ///
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")]
149 VerbatimUNC(
150 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
151 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
152 ),
153
154 /// Verbatim disk prefix, e.g., `\\?\C:`.
155 ///
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),
160
161 /// Device namespace prefix, e.g., `\\.\COM42`.
162 ///
163 /// Device namespace prefixes consist of `\\.\` immediately followed by the
164 /// device name.
165 #[stable(feature = "rust1", since = "1.0.0")]
166 DeviceNS(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
167
168 /// Prefix using Windows' _**U**niform **N**aming **C**onvention_, e.g.
169 /// `\\server\share`.
170 ///
171 /// UNC prefixes consist of the server's hostname and a share name.
172 #[stable(feature = "rust1", since = "1.0.0")]
173 UNC(
174 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
175 #[stable(feature = "rust1", since = "1.0.0")] &'a OsStr,
176 ),
177
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),
181 }
182
183 impl<'a> Prefix<'a> {
184 #[inline]
185 fn len(&self) -> usize {
186 use self::Prefix::*;
187 fn os_str_len(s: &OsStr) -> usize {
188 os_str_as_u8_slice(s).len()
189 }
190 match *self {
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 }
194 }
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),
198 Disk(_) => 2,
199 }
200 }
201
202 /// Determines if the prefix is verbatim, i.e., begins with `\\?\`.
203 ///
204 /// # Examples
205 ///
206 /// ```
207 /// use std::path::Prefix::*;
208 /// use std::ffi::OsStr;
209 ///
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());
216 /// ```
217 #[inline]
218 #[must_use]
219 #[stable(feature = "rust1", since = "1.0.0")]
220 pub fn is_verbatim(&self) -> bool {
221 use self::Prefix::*;
222 matches!(*self, Verbatim(_) | VerbatimDisk(_) | VerbatimUNC(..))
223 }
224
225 #[inline]
226 fn is_drive(&self) -> bool {
227 matches!(*self, Prefix::Disk(_))
228 }
229
230 #[inline]
231 fn has_implicit_root(&self) -> bool {
232 !self.is_drive()
233 }
234 }
235
236 ////////////////////////////////////////////////////////////////////////////////
237 // Exposed parsing helpers
238 ////////////////////////////////////////////////////////////////////////////////
239
240 /// Determines whether the character is one of the permitted path
241 /// separators for the current platform.
242 ///
243 /// # Examples
244 ///
245 /// ```
246 /// use std::path;
247 ///
248 /// assert!(path::is_separator('/')); // '/' works for both Unix and Windows
249 /// assert!(!path::is_separator('❤'));
250 /// ```
251 #[must_use]
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)
255 }
256
257 /// The primary separator of path components for the current platform.
258 ///
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;
262
263 ////////////////////////////////////////////////////////////////////////////////
264 // Misc helpers
265 ////////////////////////////////////////////////////////////////////////////////
266
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>
271 where
272 I: Iterator<Item = Component<'a>> + Clone,
273 J: Iterator<Item = Component<'b>>,
274 {
275 loop {
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,
283 }
284 iter = iter_next;
285 }
286 }
287
288 // See note at the top of this module to understand why these are used:
289 //
290 // These casts are safe as OsStr is internally a wrapper around [u8] on all
291 // platforms.
292 //
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]) }
298 }
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) }
302 }
303
304 // Detect scheme on Redox
305 fn has_redox_scheme(s: &[u8]) -> bool {
306 cfg!(target_os = "redox") && s.contains(&b':')
307 }
308
309 ////////////////////////////////////////////////////////////////////////////////
310 // Cross-platform, iterator-independent parsing
311 ////////////////////////////////////////////////////////////////////////////////
312
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])
317 }
318
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);
323 }
324
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"") {
333 (Some(file), None)
334 } else {
335 unsafe { (before.map(|s| u8_slice_as_os_str(s)), after.map(|s| u8_slice_as_os_str(s))) }
336 }
337 }
338
339 fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) {
340 let slice = os_str_as_u8_slice(file);
341 if slice == b".." {
342 return (file, None);
343 }
344
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'.') {
350 Some(i) => i + 1,
351 None => return (file, None),
352 };
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))) }
356 }
357
358 ////////////////////////////////////////////////////////////////////////////////
359 // The core iterators
360 ////////////////////////////////////////////////////////////////////////////////
361
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.
365 ///
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)]
369 enum State {
370 Prefix = 0, // c:
371 StartDir = 1, // / or . or nothing
372 Body = 2, // foo/bar/baz
373 Done = 3,
374 }
375
376 /// A structure wrapping a Windows path prefix as well as its unparsed string
377 /// representation.
378 ///
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`].
382 ///
383 /// Instances of this `struct` can be obtained by matching against the
384 /// [`Prefix` variant] on [`Component`].
385 ///
386 /// Does not occur on Unix.
387 ///
388 /// # Examples
389 ///
390 /// ```
391 /// # if cfg!(windows) {
392 /// use std::path::{Component, Path, Prefix};
393 /// use std::ffi::OsStr;
394 ///
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());
400 /// }
401 /// _ => unreachable!(),
402 /// }
403 /// # }
404 /// ```
405 ///
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.
413 raw: &'a OsStr,
414
415 /// The parsed prefix data.
416 parsed: Prefix<'a>,
417 }
418
419 impl<'a> PrefixComponent<'a> {
420 /// Returns the parsed prefix data.
421 ///
422 /// See [`Prefix`]'s documentation for more information on the different
423 /// kinds of prefixes.
424 #[stable(feature = "rust1", since = "1.0.0")]
425 #[must_use]
426 #[inline]
427 pub fn kind(&self) -> Prefix<'a> {
428 self.parsed
429 }
430
431 /// Returns the raw [`OsStr`] slice for this prefix.
432 #[stable(feature = "rust1", since = "1.0.0")]
433 #[must_use]
434 #[inline]
435 pub fn as_os_str(&self) -> &'a OsStr {
436 self.raw
437 }
438 }
439
440 #[stable(feature = "rust1", since = "1.0.0")]
441 impl<'a> cmp::PartialEq for PrefixComponent<'a> {
442 #[inline]
443 fn eq(&self, other: &PrefixComponent<'a>) -> bool {
444 cmp::PartialEq::eq(&self.parsed, &other.parsed)
445 }
446 }
447
448 #[stable(feature = "rust1", since = "1.0.0")]
449 impl<'a> cmp::PartialOrd for PrefixComponent<'a> {
450 #[inline]
451 fn partial_cmp(&self, other: &PrefixComponent<'a>) -> Option<cmp::Ordering> {
452 cmp::PartialOrd::partial_cmp(&self.parsed, &other.parsed)
453 }
454 }
455
456 #[stable(feature = "rust1", since = "1.0.0")]
457 impl cmp::Ord for PrefixComponent<'_> {
458 #[inline]
459 fn cmp(&self, other: &Self) -> cmp::Ordering {
460 cmp::Ord::cmp(&self.parsed, &other.parsed)
461 }
462 }
463
464 #[stable(feature = "rust1", since = "1.0.0")]
465 impl Hash for PrefixComponent<'_> {
466 fn hash<H: Hasher>(&self, h: &mut H) {
467 self.parsed.hash(h);
468 }
469 }
470
471 /// A single component of a path.
472 ///
473 /// A `Component` roughly corresponds to a substring between path separators
474 /// (`/` or `\`).
475 ///
476 /// This `enum` is created by iterating over [`Components`], which in turn is
477 /// created by the [`components`](Path::components) method on [`Path`].
478 ///
479 /// # Examples
480 ///
481 /// ```rust
482 /// use std::path::{Component, Path};
483 ///
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()),
491 /// ]);
492 /// ```
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`.
497 ///
498 /// There is a large variety of prefix types, see [`Prefix`]'s documentation
499 /// for more.
500 ///
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>),
504
505 /// The root directory component, appears after any prefix and before anything else.
506 ///
507 /// It represents a separator that designates that a path starts from root.
508 #[stable(feature = "rust1", since = "1.0.0")]
509 RootDir,
510
511 /// A reference to the current directory, i.e., `.`.
512 #[stable(feature = "rust1", since = "1.0.0")]
513 CurDir,
514
515 /// A reference to the parent directory, i.e., `..`.
516 #[stable(feature = "rust1", since = "1.0.0")]
517 ParentDir,
518
519 /// A normal component, e.g., `a` and `b` in `a/b`.
520 ///
521 /// This variant is the most common one, it represents references to files
522 /// or directories.
523 #[stable(feature = "rust1", since = "1.0.0")]
524 Normal(#[stable(feature = "rust1", since = "1.0.0")] &'a OsStr),
525 }
526
527 impl<'a> Component<'a> {
528 /// Extracts the underlying [`OsStr`] slice.
529 ///
530 /// # Examples
531 ///
532 /// ```
533 /// use std::path::Path;
534 ///
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"]);
538 /// ```
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 {
542 match self {
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,
548 }
549 }
550 }
551
552 #[stable(feature = "rust1", since = "1.0.0")]
553 impl AsRef<OsStr> for Component<'_> {
554 #[inline]
555 fn as_ref(&self) -> &OsStr {
556 self.as_os_str()
557 }
558 }
559
560 #[stable(feature = "path_component_asref", since = "1.25.0")]
561 impl AsRef<Path> for Component<'_> {
562 #[inline]
563 fn as_ref(&self) -> &Path {
564 self.as_os_str().as_ref()
565 }
566 }
567
568 /// An iterator over the [`Component`]s of a [`Path`].
569 ///
570 /// This `struct` is created by the [`components`] method on [`Path`].
571 /// See its documentation for more.
572 ///
573 /// # Examples
574 ///
575 /// ```
576 /// use std::path::Path;
577 ///
578 /// let path = Path::new("/tmp/foo/bar.txt");
579 ///
580 /// for component in path.components() {
581 /// println!("{:?}", component);
582 /// }
583 /// ```
584 ///
585 /// [`components`]: Path::components
586 #[derive(Clone)]
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
591 path: &'a [u8],
592
593 // The prefix as it was originally parsed, if any
594 prefix: Option<Prefix<'a>>,
595
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,
600
601 // The iterator is double-ended, and these two states keep track of what has
602 // been produced from either end
603 front: State,
604 back: State,
605 }
606
607 /// An iterator over the [`Component`]s of a [`Path`], as [`OsStr`] slices.
608 ///
609 /// This `struct` is created by the [`iter`] method on [`Path`].
610 /// See its documentation for more.
611 ///
612 /// [`iter`]: Path::iter
613 #[derive(Clone)]
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>,
618 }
619
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);
624
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()
628 }
629 }
630
631 f.debug_tuple("Components").field(&DebugHelper(self.as_path())).finish()
632 }
633 }
634
635 impl<'a> Components<'a> {
636 // how long is the prefix, if any?
637 #[inline]
638 fn prefix_len(&self) -> usize {
639 self.prefix.as_ref().map(Prefix::len).unwrap_or(0)
640 }
641
642 #[inline]
643 fn prefix_verbatim(&self) -> bool {
644 self.prefix.as_ref().map(Prefix::is_verbatim).unwrap_or(false)
645 }
646
647 /// how much of the prefix is left from the point of view of iteration?
648 #[inline]
649 fn prefix_remaining(&self) -> usize {
650 if self.front == State::Prefix { self.prefix_len() } else { 0 }
651 }
652
653 // Given the iteration so far, how much of the pre-State::Body path is left?
654 #[inline]
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
659 }
660
661 // is the iteration complete?
662 #[inline]
663 fn finished(&self) -> bool {
664 self.front == State::Done || self.back == State::Done || self.front > self.back
665 }
666
667 #[inline]
668 fn is_sep_byte(&self, b: u8) -> bool {
669 if self.prefix_verbatim() { is_verbatim_sep(b) } else { is_sep_byte(b) }
670 }
671
672 /// Extracts a slice corresponding to the portion of the path remaining for iteration.
673 ///
674 /// # Examples
675 ///
676 /// ```
677 /// use std::path::Path;
678 ///
679 /// let mut components = Path::new("/tmp/foo/bar.txt").components();
680 /// components.next();
681 /// components.next();
682 ///
683 /// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
684 /// ```
685 #[must_use]
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 {
690 comps.trim_left();
691 }
692 if comps.back == State::Body {
693 comps.trim_right();
694 }
695 unsafe { Path::from_u8_slice(comps.path) }
696 }
697
698 /// Is the *original* path rooted?
699 fn has_root(&self) -> bool {
700 if self.has_physical_root {
701 return true;
702 }
703 if let Some(p) = self.prefix {
704 if p.has_implicit_root() {
705 return true;
706 }
707 }
708 false
709 }
710
711 /// Should the normalized path include a leading . ?
712 fn include_cur_dir(&self) -> bool {
713 if self.has_root() {
714 return false;
715 }
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),
720 _ => false,
721 }
722 }
723
724 // parse a given byte sequence into the corresponding path component
725 fn parse_single_component<'b>(&self, comp: &'b [u8]) -> Option<Component<'b>> {
726 match comp {
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),
732 b"" => None,
733 _ => Some(Component::Normal(unsafe { u8_slice_as_os_str(comp) })),
734 }
735 }
736
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]),
744 };
745 (comp.len() + extra, self.parse_single_component(comp))
746 }
747
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..]),
756 };
757 (comp.len() + extra, self.parse_single_component(comp))
758 }
759
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();
764 if comp.is_some() {
765 return;
766 } else {
767 self.path = &self.path[size..];
768 }
769 }
770 }
771
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();
776 if comp.is_some() {
777 return;
778 } else {
779 self.path = &self.path[..self.path.len() - size];
780 }
781 }
782 }
783 }
784
785 #[stable(feature = "rust1", since = "1.0.0")]
786 impl AsRef<Path> for Components<'_> {
787 #[inline]
788 fn as_ref(&self) -> &Path {
789 self.as_path()
790 }
791 }
792
793 #[stable(feature = "rust1", since = "1.0.0")]
794 impl AsRef<OsStr> for Components<'_> {
795 #[inline]
796 fn as_ref(&self) -> &OsStr {
797 self.as_path().as_os_str()
798 }
799 }
800
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);
805
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()
809 }
810 }
811
812 f.debug_tuple("Iter").field(&DebugHelper(self.as_path())).finish()
813 }
814 }
815
816 impl<'a> Iter<'a> {
817 /// Extracts a slice corresponding to the portion of the path remaining for iteration.
818 ///
819 /// # Examples
820 ///
821 /// ```
822 /// use std::path::Path;
823 ///
824 /// let mut iter = Path::new("/tmp/foo/bar.txt").iter();
825 /// iter.next();
826 /// iter.next();
827 ///
828 /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
829 /// ```
830 #[stable(feature = "rust1", since = "1.0.0")]
831 #[must_use]
832 #[inline]
833 pub fn as_path(&self) -> &'a Path {
834 self.inner.as_path()
835 }
836 }
837
838 #[stable(feature = "rust1", since = "1.0.0")]
839 impl AsRef<Path> for Iter<'_> {
840 #[inline]
841 fn as_ref(&self) -> &Path {
842 self.as_path()
843 }
844 }
845
846 #[stable(feature = "rust1", since = "1.0.0")]
847 impl AsRef<OsStr> for Iter<'_> {
848 #[inline]
849 fn as_ref(&self) -> &OsStr {
850 self.as_path().as_os_str()
851 }
852 }
853
854 #[stable(feature = "rust1", since = "1.0.0")]
855 impl<'a> Iterator for Iter<'a> {
856 type Item = &'a OsStr;
857
858 #[inline]
859 fn next(&mut self) -> Option<&'a OsStr> {
860 self.inner.next().map(Component::as_os_str)
861 }
862 }
863
864 #[stable(feature = "rust1", since = "1.0.0")]
865 impl<'a> DoubleEndedIterator for Iter<'a> {
866 #[inline]
867 fn next_back(&mut self) -> Option<&'a OsStr> {
868 self.inner.next_back().map(Component::as_os_str)
869 }
870 }
871
872 #[stable(feature = "fused", since = "1.26.0")]
873 impl FusedIterator for Iter<'_> {}
874
875 #[stable(feature = "rust1", since = "1.0.0")]
876 impl<'a> Iterator for Components<'a> {
877 type Item = Component<'a>;
878
879 fn next(&mut self) -> Option<Component<'a>> {
880 while !self.finished() {
881 match self.front {
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(),
890 }));
891 }
892 State::Prefix => {
893 self.front = State::StartDir;
894 }
895 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);
904 }
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);
909 }
910 }
911 State::Body if !self.path.is_empty() => {
912 let (size, comp) = self.parse_next_component();
913 self.path = &self.path[size..];
914 if comp.is_some() {
915 return comp;
916 }
917 }
918 State::Body => {
919 self.front = State::Done;
920 }
921 State::Done => unreachable!(),
922 }
923 }
924 None
925 }
926 }
927
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() {
932 match self.back {
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];
936 if comp.is_some() {
937 return comp;
938 }
939 }
940 State::Body => {
941 self.back = State::StartDir;
942 }
943 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);
951 }
952 } else if self.include_cur_dir() {
953 self.path = &self.path[..self.path.len() - 1];
954 return Some(Component::CurDir);
955 }
956 }
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(),
962 }));
963 }
964 State::Prefix => {
965 self.back = State::Done;
966 return None;
967 }
968 State::Done => unreachable!(),
969 }
970 }
971 None
972 }
973 }
974
975 #[stable(feature = "fused", since = "1.26.0")]
976 impl FusedIterator for Components<'_> {}
977
978 #[stable(feature = "rust1", since = "1.0.0")]
979 impl<'a> cmp::PartialEq for Components<'a> {
980 #[inline]
981 fn eq(&self, other: &Components<'a>) -> bool {
982 let Components { path: _, front: _, back: _, has_physical_root: _, prefix: _ } = self;
983
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()
992 {
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 {
996 return true;
997 }
998 }
999
1000 // compare back to front since absolute paths often share long prefixes
1001 Iterator::eq(self.clone().rev(), other.clone().rev())
1002 }
1003 }
1004
1005 #[stable(feature = "rust1", since = "1.0.0")]
1006 impl cmp::Eq for Components<'_> {}
1007
1008 #[stable(feature = "rust1", since = "1.0.0")]
1009 impl<'a> cmp::PartialOrd for Components<'a> {
1010 #[inline]
1011 fn partial_cmp(&self, other: &Components<'a>) -> Option<cmp::Ordering> {
1012 Some(compare_components(self.clone(), other.clone()))
1013 }
1014 }
1015
1016 #[stable(feature = "rust1", since = "1.0.0")]
1017 impl cmp::Ord for Components<'_> {
1018 #[inline]
1019 fn cmp(&self, other: &Self) -> cmp::Ordering {
1020 compare_components(self.clone(), other.clone())
1021 }
1022 }
1023
1024 fn compare_components(mut left: Components<'_>, mut right: Components<'_>) -> cmp::Ordering {
1025 // Fast path for long shared prefixes
1026 //
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
1031 //
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()),
1039 Some(diff) => diff,
1040 };
1041
1042 if let Some(previous_sep) =
1043 left.path[..first_difference].iter().rposition(|&b| left.is_sep_byte(b))
1044 {
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;
1050 }
1051 }
1052
1053 Iterator::cmp(left, right)
1054 }
1055
1056 /// An iterator over [`Path`] and its ancestors.
1057 ///
1058 /// This `struct` is created by the [`ancestors`] method on [`Path`].
1059 /// See its documentation for more.
1060 ///
1061 /// # Examples
1062 ///
1063 /// ```
1064 /// use std::path::Path;
1065 ///
1066 /// let path = Path::new("/foo/bar");
1067 ///
1068 /// for ancestor in path.ancestors() {
1069 /// println!("{}", ancestor.display());
1070 /// }
1071 /// ```
1072 ///
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>,
1079 }
1080
1081 #[stable(feature = "path_ancestors", since = "1.28.0")]
1082 impl<'a> Iterator for Ancestors<'a> {
1083 type Item = &'a Path;
1084
1085 #[inline]
1086 fn next(&mut self) -> Option<Self::Item> {
1087 let next = self.next;
1088 self.next = next.and_then(Path::parent);
1089 next
1090 }
1091 }
1092
1093 #[stable(feature = "path_ancestors", since = "1.28.0")]
1094 impl FusedIterator for Ancestors<'_> {}
1095
1096 ////////////////////////////////////////////////////////////////////////////////
1097 // Basic types and traits
1098 ////////////////////////////////////////////////////////////////////////////////
1099
1100 /// An owned, mutable path (akin to [`String`]).
1101 ///
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.
1105 ///
1106 /// [`push`]: PathBuf::push
1107 /// [`set_extension`]: PathBuf::set_extension
1108 ///
1109 /// More details about the overall approach can be found in
1110 /// the [module documentation](self).
1111 ///
1112 /// # Examples
1113 ///
1114 /// You can use [`push`] to build up a `PathBuf` from
1115 /// components:
1116 ///
1117 /// ```
1118 /// use std::path::PathBuf;
1119 ///
1120 /// let mut path = PathBuf::new();
1121 ///
1122 /// path.push(r"C:\");
1123 /// path.push("windows");
1124 /// path.push("system32");
1125 ///
1126 /// path.set_extension("dll");
1127 /// ```
1128 ///
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:
1131 ///
1132 /// ```
1133 /// use std::path::PathBuf;
1134 ///
1135 /// let path: PathBuf = [r"C:\", "windows", "system32.dll"].iter().collect();
1136 /// ```
1137 ///
1138 /// We can still do better than this! Since these are all strings, we can use
1139 /// `From::from`:
1140 ///
1141 /// ```
1142 /// use std::path::PathBuf;
1143 ///
1144 /// let path = PathBuf::from(r"C:\windows\system32.dll");
1145 /// ```
1146 ///
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")]
1150 // FIXME:
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 {
1157 inner: OsString,
1158 }
1159
1160 impl PathBuf {
1161 #[inline]
1162 fn as_mut_vec(&mut self) -> &mut Vec<u8> {
1163 unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) }
1164 }
1165
1166 /// Allocates an empty `PathBuf`.
1167 ///
1168 /// # Examples
1169 ///
1170 /// ```
1171 /// use std::path::PathBuf;
1172 ///
1173 /// let path = PathBuf::new();
1174 /// ```
1175 #[stable(feature = "rust1", since = "1.0.0")]
1176 #[must_use]
1177 #[inline]
1178 pub fn new() -> PathBuf {
1179 PathBuf { inner: OsString::new() }
1180 }
1181
1182 /// Creates a new `PathBuf` with a given capacity used to create the
1183 /// internal [`OsString`]. See [`with_capacity`] defined on [`OsString`].
1184 ///
1185 /// # Examples
1186 ///
1187 /// ```
1188 /// use std::path::PathBuf;
1189 ///
1190 /// let mut path = PathBuf::with_capacity(10);
1191 /// let capacity = path.capacity();
1192 ///
1193 /// // This push is done without reallocating
1194 /// path.push(r"C:\");
1195 ///
1196 /// assert_eq!(capacity, path.capacity());
1197 /// ```
1198 ///
1199 /// [`with_capacity`]: OsString::with_capacity
1200 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1201 #[must_use]
1202 #[inline]
1203 pub fn with_capacity(capacity: usize) -> PathBuf {
1204 PathBuf { inner: OsString::with_capacity(capacity) }
1205 }
1206
1207 /// Coerces to a [`Path`] slice.
1208 ///
1209 /// # Examples
1210 ///
1211 /// ```
1212 /// use std::path::{Path, PathBuf};
1213 ///
1214 /// let p = PathBuf::from("/test");
1215 /// assert_eq!(Path::new("/test"), p.as_path());
1216 /// ```
1217 #[stable(feature = "rust1", since = "1.0.0")]
1218 #[must_use]
1219 #[inline]
1220 pub fn as_path(&self) -> &Path {
1221 self
1222 }
1223
1224 /// Extends `self` with `path`.
1225 ///
1226 /// If `path` is absolute, it replaces the current path.
1227 ///
1228 /// On Windows:
1229 ///
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.
1236 ///
1237 /// # Examples
1238 ///
1239 /// Pushing a relative path extends the existing path:
1240 ///
1241 /// ```
1242 /// use std::path::PathBuf;
1243 ///
1244 /// let mut path = PathBuf::from("/tmp");
1245 /// path.push("file.bk");
1246 /// assert_eq!(path, PathBuf::from("/tmp/file.bk"));
1247 /// ```
1248 ///
1249 /// Pushing an absolute path replaces the existing path:
1250 ///
1251 /// ```
1252 /// use std::path::PathBuf;
1253 ///
1254 /// let mut path = PathBuf::from("/tmp");
1255 /// path.push("/etc");
1256 /// assert_eq!(path, PathBuf::from("/etc"));
1257 /// ```
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())
1261 }
1262
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);
1266
1267 // in the special case of `C:` on Windows, do *not* add a separator
1268 let comps = self.components();
1269
1270 if comps.prefix_len() > 0
1271 && comps.prefix_len() == comps.path.len()
1272 && comps.prefix.unwrap().is_drive()
1273 {
1274 need_sep = false
1275 }
1276
1277 // absolute `path` replaces `self`
1278 if path.is_absolute() || path.prefix().is_some() {
1279 self.as_mut_vec().truncate(0);
1280
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() {
1285 match c {
1286 Component::RootDir => {
1287 buf.truncate(1);
1288 buf.push(c);
1289 }
1290 Component::CurDir => (),
1291 Component::ParentDir => {
1292 if let Some(Component::Normal(_)) = buf.last() {
1293 buf.pop();
1294 }
1295 }
1296 _ => buf.push(c),
1297 }
1298 }
1299
1300 let mut res = OsString::new();
1301 let mut need_sep = false;
1302
1303 for c in buf {
1304 if need_sep && c != Component::RootDir {
1305 res.push(MAIN_SEP_STR);
1306 }
1307 res.push(c.as_os_str());
1308
1309 need_sep = match c {
1310 Component::RootDir => false,
1311 Component::Prefix(prefix) => {
1312 !prefix.parsed.is_drive() && prefix.parsed.len() > 0
1313 }
1314 _ => true,
1315 }
1316 }
1317
1318 self.inner = res;
1319 return;
1320
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);
1325
1326 // `path` is a pure relative path
1327 } else if need_sep {
1328 self.inner.push(MAIN_SEP_STR);
1329 }
1330
1331 self.inner.push(path);
1332 }
1333
1334 /// Truncates `self` to [`self.parent`].
1335 ///
1336 /// Returns `false` and does nothing if [`self.parent`] is [`None`].
1337 /// Otherwise, returns `true`.
1338 ///
1339 /// [`self.parent`]: Path::parent
1340 ///
1341 /// # Examples
1342 ///
1343 /// ```
1344 /// use std::path::{Path, PathBuf};
1345 ///
1346 /// let mut p = PathBuf::from("/spirited/away.rs");
1347 ///
1348 /// p.pop();
1349 /// assert_eq!(Path::new("/spirited"), p);
1350 /// p.pop();
1351 /// assert_eq!(Path::new("/"), p);
1352 /// ```
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()) {
1356 Some(len) => {
1357 self.as_mut_vec().truncate(len);
1358 true
1359 }
1360 None => false,
1361 }
1362 }
1363
1364 /// Updates [`self.file_name`] to `file_name`.
1365 ///
1366 /// If [`self.file_name`] was [`None`], this is equivalent to pushing
1367 /// `file_name`.
1368 ///
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.)
1372 ///
1373 /// [`self.file_name`]: Path::file_name
1374 /// [`pop`]: PathBuf::pop
1375 ///
1376 /// # Examples
1377 ///
1378 /// ```
1379 /// use std::path::PathBuf;
1380 ///
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"));
1388 /// ```
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())
1392 }
1393
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);
1398 }
1399 self.push(file_name);
1400 }
1401
1402 /// Updates [`self.extension`] to `extension`.
1403 ///
1404 /// Returns `false` and does nothing if [`self.file_name`] is [`None`],
1405 /// returns `true` and updates the extension otherwise.
1406 ///
1407 /// If [`self.extension`] is [`None`], the extension is added; otherwise
1408 /// it is replaced.
1409 ///
1410 /// [`self.file_name`]: Path::file_name
1411 /// [`self.extension`]: Path::extension
1412 ///
1413 /// # Examples
1414 ///
1415 /// ```
1416 /// use std::path::{Path, PathBuf};
1417 ///
1418 /// let mut p = PathBuf::from("/feel/the");
1419 ///
1420 /// p.set_extension("force");
1421 /// assert_eq!(Path::new("/feel/the.force"), p.as_path());
1422 ///
1423 /// p.set_extension("dark_side");
1424 /// assert_eq!(Path::new("/feel/the.dark_side"), p.as_path());
1425 /// ```
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())
1429 }
1430
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),
1435 };
1436
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));
1442
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);
1447 v.push(b'.');
1448 v.extend_from_slice(new);
1449 }
1450
1451 true
1452 }
1453
1454 /// Consumes the `PathBuf`, yielding its internal [`OsString`] storage.
1455 ///
1456 /// # Examples
1457 ///
1458 /// ```
1459 /// use std::path::PathBuf;
1460 ///
1461 /// let p = PathBuf::from("/the/head");
1462 /// let os_str = p.into_os_string();
1463 /// ```
1464 #[stable(feature = "rust1", since = "1.0.0")]
1465 #[must_use = "`self` will be dropped if the result is not used"]
1466 #[inline]
1467 pub fn into_os_string(self) -> OsString {
1468 self.inner
1469 }
1470
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"]
1474 #[inline]
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) }
1478 }
1479
1480 /// Invokes [`capacity`] on the underlying instance of [`OsString`].
1481 ///
1482 /// [`capacity`]: OsString::capacity
1483 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1484 #[must_use]
1485 #[inline]
1486 pub fn capacity(&self) -> usize {
1487 self.inner.capacity()
1488 }
1489
1490 /// Invokes [`clear`] on the underlying instance of [`OsString`].
1491 ///
1492 /// [`clear`]: OsString::clear
1493 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1494 #[inline]
1495 pub fn clear(&mut self) {
1496 self.inner.clear()
1497 }
1498
1499 /// Invokes [`reserve`] on the underlying instance of [`OsString`].
1500 ///
1501 /// [`reserve`]: OsString::reserve
1502 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1503 #[inline]
1504 pub fn reserve(&mut self, additional: usize) {
1505 self.inner.reserve(additional)
1506 }
1507
1508 /// Invokes [`reserve_exact`] on the underlying instance of [`OsString`].
1509 ///
1510 /// [`reserve_exact`]: OsString::reserve_exact
1511 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1512 #[inline]
1513 pub fn reserve_exact(&mut self, additional: usize) {
1514 self.inner.reserve_exact(additional)
1515 }
1516
1517 /// Invokes [`shrink_to_fit`] on the underlying instance of [`OsString`].
1518 ///
1519 /// [`shrink_to_fit`]: OsString::shrink_to_fit
1520 #[stable(feature = "path_buf_capacity", since = "1.44.0")]
1521 #[inline]
1522 pub fn shrink_to_fit(&mut self) {
1523 self.inner.shrink_to_fit()
1524 }
1525
1526 /// Invokes [`shrink_to`] on the underlying instance of [`OsString`].
1527 ///
1528 /// [`shrink_to`]: OsString::shrink_to
1529 #[stable(feature = "shrink_to", since = "1.56.0")]
1530 #[inline]
1531 pub fn shrink_to(&mut self, min_capacity: usize) {
1532 self.inner.shrink_to(min_capacity)
1533 }
1534 }
1535
1536 #[stable(feature = "rust1", since = "1.0.0")]
1537 impl Clone for PathBuf {
1538 #[inline]
1539 fn clone(&self) -> Self {
1540 PathBuf { inner: self.inner.clone() }
1541 }
1542
1543 #[inline]
1544 fn clone_from(&mut self, source: &Self) {
1545 self.inner.clone_from(&source.inner)
1546 }
1547 }
1548
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.
1552 ///
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) }
1558 }
1559 }
1560
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.
1564 ///
1565 /// Converting from a `Cow::Owned` does not clone or allocate.
1566 #[inline]
1567 fn from(cow: Cow<'_, Path>) -> Box<Path> {
1568 match cow {
1569 Cow::Borrowed(path) => Box::from(path),
1570 Cow::Owned(path) => Box::from(path),
1571 }
1572 }
1573 }
1574
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`
1578 ///
1579 /// This conversion does not allocate or copy memory.
1580 #[inline]
1581 fn from(boxed: Box<Path>) -> PathBuf {
1582 boxed.into_path_buf()
1583 }
1584 }
1585
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>`
1589 ///
1590 /// This conversion currently should not allocate memory,
1591 /// but this behavior is not guaranteed on all platforms or in all future versions.
1592 #[inline]
1593 fn from(p: PathBuf) -> Box<Path> {
1594 p.into_boxed_path()
1595 }
1596 }
1597
1598 #[stable(feature = "more_box_slice_clone", since = "1.29.0")]
1599 impl Clone for Box<Path> {
1600 #[inline]
1601 fn clone(&self) -> Self {
1602 self.to_path_buf().into_boxed_path()
1603 }
1604 }
1605
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`.
1609 ///
1610 /// Allocates a [`PathBuf`] and copies the data into it.
1611 #[inline]
1612 fn from(s: &T) -> PathBuf {
1613 PathBuf::from(s.as_ref().to_os_string())
1614 }
1615 }
1616
1617 #[stable(feature = "rust1", since = "1.0.0")]
1618 impl From<OsString> for PathBuf {
1619 /// Converts an [`OsString`] into a [`PathBuf`]
1620 ///
1621 /// This conversion does not allocate or copy memory.
1622 #[inline]
1623 fn from(s: OsString) -> PathBuf {
1624 PathBuf { inner: s }
1625 }
1626 }
1627
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`]
1631 ///
1632 /// This conversion does not allocate or copy memory.
1633 #[inline]
1634 fn from(path_buf: PathBuf) -> OsString {
1635 path_buf.inner
1636 }
1637 }
1638
1639 #[stable(feature = "rust1", since = "1.0.0")]
1640 impl From<String> for PathBuf {
1641 /// Converts a [`String`] into a [`PathBuf`]
1642 ///
1643 /// This conversion does not allocate or copy memory.
1644 #[inline]
1645 fn from(s: String) -> PathBuf {
1646 PathBuf::from(OsString::from(s))
1647 }
1648 }
1649
1650 #[stable(feature = "path_from_str", since = "1.32.0")]
1651 impl FromStr for PathBuf {
1652 type Err = core::convert::Infallible;
1653
1654 #[inline]
1655 fn from_str(s: &str) -> Result<Self, Self::Err> {
1656 Ok(PathBuf::from(s))
1657 }
1658 }
1659
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();
1664 buf.extend(iter);
1665 buf
1666 }
1667 }
1668
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()));
1673 }
1674
1675 #[inline]
1676 fn extend_one(&mut self, p: P) {
1677 self.push(p.as_ref());
1678 }
1679 }
1680
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)
1685 }
1686 }
1687
1688 #[stable(feature = "rust1", since = "1.0.0")]
1689 impl ops::Deref for PathBuf {
1690 type Target = Path;
1691 #[inline]
1692 fn deref(&self) -> &Path {
1693 Path::new(&self.inner)
1694 }
1695 }
1696
1697 #[stable(feature = "rust1", since = "1.0.0")]
1698 impl Borrow<Path> for PathBuf {
1699 #[inline]
1700 fn borrow(&self) -> &Path {
1701 self.deref()
1702 }
1703 }
1704
1705 #[stable(feature = "default_for_pathbuf", since = "1.17.0")]
1706 impl Default for PathBuf {
1707 #[inline]
1708 fn default() -> Self {
1709 PathBuf::new()
1710 }
1711 }
1712
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
1716 /// [`Path`].
1717 ///
1718 /// This conversion does not clone or allocate.
1719 #[inline]
1720 fn from(s: &'a Path) -> Cow<'a, Path> {
1721 Cow::Borrowed(s)
1722 }
1723 }
1724
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`].
1729 ///
1730 /// This conversion does not clone or allocate.
1731 #[inline]
1732 fn from(s: PathBuf) -> Cow<'a, Path> {
1733 Cow::Owned(s)
1734 }
1735 }
1736
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
1740 /// [`PathBuf`].
1741 ///
1742 /// This conversion does not clone or allocate.
1743 #[inline]
1744 fn from(p: &'a PathBuf) -> Cow<'a, Path> {
1745 Cow::Borrowed(p.as_path())
1746 }
1747 }
1748
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.
1752 ///
1753 /// Converting from a `Cow::Owned` does not clone or allocate.
1754 #[inline]
1755 fn from(p: Cow<'a, Path>) -> Self {
1756 p.into_owned()
1757 }
1758 }
1759
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.
1763 #[inline]
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) }
1767 }
1768 }
1769
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.
1773 #[inline]
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) }
1777 }
1778 }
1779
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.
1783 #[inline]
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) }
1787 }
1788 }
1789
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.
1793 #[inline]
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) }
1797 }
1798 }
1799
1800 #[stable(feature = "rust1", since = "1.0.0")]
1801 impl ToOwned for Path {
1802 type Owned = PathBuf;
1803 #[inline]
1804 fn to_owned(&self) -> PathBuf {
1805 self.to_path_buf()
1806 }
1807 #[inline]
1808 fn clone_into(&self, target: &mut PathBuf) {
1809 self.inner.clone_into(&mut target.inner);
1810 }
1811 }
1812
1813 #[stable(feature = "rust1", since = "1.0.0")]
1814 impl cmp::PartialEq for PathBuf {
1815 #[inline]
1816 fn eq(&self, other: &PathBuf) -> bool {
1817 self.components() == other.components()
1818 }
1819 }
1820
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)
1825 }
1826 }
1827
1828 #[stable(feature = "rust1", since = "1.0.0")]
1829 impl cmp::Eq for PathBuf {}
1830
1831 #[stable(feature = "rust1", since = "1.0.0")]
1832 impl cmp::PartialOrd for PathBuf {
1833 #[inline]
1834 fn partial_cmp(&self, other: &PathBuf) -> Option<cmp::Ordering> {
1835 Some(compare_components(self.components(), other.components()))
1836 }
1837 }
1838
1839 #[stable(feature = "rust1", since = "1.0.0")]
1840 impl cmp::Ord for PathBuf {
1841 #[inline]
1842 fn cmp(&self, other: &PathBuf) -> cmp::Ordering {
1843 compare_components(self.components(), other.components())
1844 }
1845 }
1846
1847 #[stable(feature = "rust1", since = "1.0.0")]
1848 impl AsRef<OsStr> for PathBuf {
1849 #[inline]
1850 fn as_ref(&self) -> &OsStr {
1851 &self.inner[..]
1852 }
1853 }
1854
1855 /// A slice of a path (akin to [`str`]).
1856 ///
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.
1861 ///
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`].
1865 ///
1866 /// More details about the overall approach can be found in
1867 /// the [module documentation](self).
1868 ///
1869 /// # Examples
1870 ///
1871 /// ```
1872 /// use std::path::Path;
1873 /// use std::ffi::OsStr;
1874 ///
1875 /// // Note: this example does work on Windows
1876 /// let path = Path::new("./foo/bar.txt");
1877 ///
1878 /// let parent = path.parent();
1879 /// assert_eq!(parent, Some(Path::new("./foo")));
1880 ///
1881 /// let file_stem = path.file_stem();
1882 /// assert_eq!(file_stem, Some(OsStr::new("bar")));
1883 ///
1884 /// let extension = path.extension();
1885 /// assert_eq!(extension, Some(OsStr::new("txt")));
1886 /// ```
1887 #[cfg_attr(not(test), rustc_diagnostic_item = "Path")]
1888 #[stable(feature = "rust1", since = "1.0.0")]
1889 // FIXME:
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.
1895 pub struct Path {
1896 inner: OsStr,
1897 }
1898
1899 /// An error returned from [`Path::strip_prefix`] if the prefix was not found.
1900 ///
1901 /// This `struct` is created by the [`strip_prefix`] method on [`Path`].
1902 /// See its documentation for more.
1903 ///
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(());
1908
1909 impl Path {
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)) }
1914 }
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)
1918 }
1919
1920 /// Directly wraps a string slice as a `Path` slice.
1921 ///
1922 /// This is a cost-free conversion.
1923 ///
1924 /// # Examples
1925 ///
1926 /// ```
1927 /// use std::path::Path;
1928 ///
1929 /// Path::new("foo.txt");
1930 /// ```
1931 ///
1932 /// You can create `Path`s from `String`s, or even other `Path`s:
1933 ///
1934 /// ```
1935 /// use std::path::Path;
1936 ///
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);
1941 /// ```
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) }
1945 }
1946
1947 /// Yields the underlying [`OsStr`] slice.
1948 ///
1949 /// # Examples
1950 ///
1951 /// ```
1952 /// use std::path::Path;
1953 ///
1954 /// let os_str = Path::new("foo.txt").as_os_str();
1955 /// assert_eq!(os_str, std::ffi::OsStr::new("foo.txt"));
1956 /// ```
1957 #[stable(feature = "rust1", since = "1.0.0")]
1958 #[must_use]
1959 #[inline]
1960 pub fn as_os_str(&self) -> &OsStr {
1961 &self.inner
1962 }
1963
1964 /// Yields a [`&str`] slice if the `Path` is valid unicode.
1965 ///
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.
1969 ///
1970 /// [`&str`]: str
1971 ///
1972 /// # Examples
1973 ///
1974 /// ```
1975 /// use std::path::Path;
1976 ///
1977 /// let path = Path::new("foo.txt");
1978 /// assert_eq!(path.to_str(), Some("foo.txt"));
1979 /// ```
1980 #[stable(feature = "rust1", since = "1.0.0")]
1981 #[must_use = "this returns the result of the operation, \
1982 without modifying the original"]
1983 #[inline]
1984 pub fn to_str(&self) -> Option<&str> {
1985 self.inner.to_str()
1986 }
1987
1988 /// Converts a `Path` to a [`Cow<str>`].
1989 ///
1990 /// Any non-Unicode sequences are replaced with
1991 /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
1992 ///
1993 /// [U+FFFD]: super::char::REPLACEMENT_CHARACTER
1994 ///
1995 /// # Examples
1996 ///
1997 /// Calling `to_string_lossy` on a `Path` with valid unicode:
1998 ///
1999 /// ```
2000 /// use std::path::Path;
2001 ///
2002 /// let path = Path::new("foo.txt");
2003 /// assert_eq!(path.to_string_lossy(), "foo.txt");
2004 /// ```
2005 ///
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"]
2011 #[inline]
2012 pub fn to_string_lossy(&self) -> Cow<'_, str> {
2013 self.inner.to_string_lossy()
2014 }
2015
2016 /// Converts a `Path` to an owned [`PathBuf`].
2017 ///
2018 /// # Examples
2019 ///
2020 /// ```
2021 /// use std::path::Path;
2022 ///
2023 /// let path_buf = Path::new("foo.txt").to_path_buf();
2024 /// assert_eq!(path_buf, std::path::PathBuf::from("foo.txt"));
2025 /// ```
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())
2032 }
2033
2034 /// Returns `true` if the `Path` is absolute, i.e., if it is independent of
2035 /// the current directory.
2036 ///
2037 /// * On Unix, a path is absolute if it starts with the root, so
2038 /// `is_absolute` and [`has_root`] are equivalent.
2039 ///
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.
2042 ///
2043 /// # Examples
2044 ///
2045 /// ```
2046 /// use std::path::Path;
2047 ///
2048 /// assert!(!Path::new("foo.txt").is_absolute());
2049 /// ```
2050 ///
2051 /// [`has_root`]: Path::has_root
2052 #[stable(feature = "rust1", since = "1.0.0")]
2053 #[must_use]
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())
2059 } else {
2060 self.has_root() && (cfg!(any(unix, target_os = "wasi")) || self.prefix().is_some())
2061 }
2062 }
2063
2064 /// Returns `true` if the `Path` is relative, i.e., not absolute.
2065 ///
2066 /// See [`is_absolute`]'s documentation for more details.
2067 ///
2068 /// # Examples
2069 ///
2070 /// ```
2071 /// use std::path::Path;
2072 ///
2073 /// assert!(Path::new("foo.txt").is_relative());
2074 /// ```
2075 ///
2076 /// [`is_absolute`]: Path::is_absolute
2077 #[stable(feature = "rust1", since = "1.0.0")]
2078 #[must_use]
2079 #[inline]
2080 pub fn is_relative(&self) -> bool {
2081 !self.is_absolute()
2082 }
2083
2084 fn prefix(&self) -> Option<Prefix<'_>> {
2085 self.components().prefix
2086 }
2087
2088 /// Returns `true` if the `Path` has a root.
2089 ///
2090 /// * On Unix, a path has a root if it begins with `/`.
2091 ///
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`
2096 ///
2097 /// # Examples
2098 ///
2099 /// ```
2100 /// use std::path::Path;
2101 ///
2102 /// assert!(Path::new("/etc/passwd").has_root());
2103 /// ```
2104 #[stable(feature = "rust1", since = "1.0.0")]
2105 #[must_use]
2106 #[inline]
2107 pub fn has_root(&self) -> bool {
2108 self.components().has_root()
2109 }
2110
2111 /// Returns the `Path` without its final component, if there is one.
2112 ///
2113 /// Returns [`None`] if the path terminates in a root or prefix.
2114 ///
2115 /// # Examples
2116 ///
2117 /// ```
2118 /// use std::path::Path;
2119 ///
2120 /// let path = Path::new("/foo/bar");
2121 /// let parent = path.parent().unwrap();
2122 /// assert_eq!(parent, Path::new("/foo"));
2123 ///
2124 /// let grand_parent = parent.parent().unwrap();
2125 /// assert_eq!(grand_parent, Path::new("/"));
2126 /// assert_eq!(grand_parent.parent(), None);
2127 /// ```
2128 #[stable(feature = "rust1", since = "1.0.0")]
2129 #[must_use]
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())
2136 }
2137 _ => None,
2138 })
2139 }
2140
2141 /// Produces an iterator over `Path` and its ancestors.
2142 ///
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,
2147 /// namely `&self`.
2148 ///
2149 /// # Examples
2150 ///
2151 /// ```
2152 /// use std::path::Path;
2153 ///
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);
2159 ///
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);
2166 /// ```
2167 ///
2168 /// [`parent`]: Path::parent
2169 #[stable(feature = "path_ancestors", since = "1.28.0")]
2170 #[inline]
2171 pub fn ancestors(&self) -> Ancestors<'_> {
2172 Ancestors { next: Some(&self) }
2173 }
2174
2175 /// Returns the final component of the `Path`, if there is one.
2176 ///
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.
2179 ///
2180 /// Returns [`None`] if the path terminates in `..`.
2181 ///
2182 /// # Examples
2183 ///
2184 /// ```
2185 /// use std::path::Path;
2186 /// use std::ffi::OsStr;
2187 ///
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());
2194 /// ```
2195 #[stable(feature = "rust1", since = "1.0.0")]
2196 #[must_use]
2197 pub fn file_name(&self) -> Option<&OsStr> {
2198 self.components().next_back().and_then(|p| match p {
2199 Component::Normal(p) => Some(p),
2200 _ => None,
2201 })
2202 }
2203
2204 /// Returns a path that, when joined onto `base`, yields `self`.
2205 ///
2206 /// # Errors
2207 ///
2208 /// If `base` is not a prefix of `self` (i.e., [`starts_with`]
2209 /// returns `false`), returns [`Err`].
2210 ///
2211 /// [`starts_with`]: Path::starts_with
2212 ///
2213 /// # Examples
2214 ///
2215 /// ```
2216 /// use std::path::{Path, PathBuf};
2217 ///
2218 /// let path = Path::new("/test/haha/foo.txt");
2219 ///
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("")));
2225 ///
2226 /// assert!(path.strip_prefix("test").is_err());
2227 /// assert!(path.strip_prefix("/haha").is_err());
2228 ///
2229 /// let prefix = PathBuf::from("/test/");
2230 /// assert_eq!(path.strip_prefix(prefix), Ok(Path::new("haha/foo.txt")));
2231 /// ```
2232 #[stable(since = "1.7.0", feature = "path_strip_prefix")]
2233 pub fn strip_prefix<P>(&self, base: P) -> Result<&Path, StripPrefixError>
2234 where
2235 P: AsRef<Path>,
2236 {
2237 self._strip_prefix(base.as_ref())
2238 }
2239
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(()))
2244 }
2245
2246 /// Determines whether `base` is a prefix of `self`.
2247 ///
2248 /// Only considers whole path components to match.
2249 ///
2250 /// # Examples
2251 ///
2252 /// ```
2253 /// use std::path::Path;
2254 ///
2255 /// let path = Path::new("/etc/passwd");
2256 ///
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
2262 ///
2263 /// assert!(!path.starts_with("/e"));
2264 /// assert!(!path.starts_with("/etc/passwd.txt"));
2265 ///
2266 /// assert!(!Path::new("/etc/foo.rs").starts_with("/etc/foo"));
2267 /// ```
2268 #[stable(feature = "rust1", since = "1.0.0")]
2269 #[must_use]
2270 pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
2271 self._starts_with(base.as_ref())
2272 }
2273
2274 fn _starts_with(&self, base: &Path) -> bool {
2275 iter_after(self.components(), base.components()).is_some()
2276 }
2277
2278 /// Determines whether `child` is a suffix of `self`.
2279 ///
2280 /// Only considers whole path components to match.
2281 ///
2282 /// # Examples
2283 ///
2284 /// ```
2285 /// use std::path::Path;
2286 ///
2287 /// let path = Path::new("/etc/resolv.conf");
2288 ///
2289 /// assert!(path.ends_with("resolv.conf"));
2290 /// assert!(path.ends_with("etc/resolv.conf"));
2291 /// assert!(path.ends_with("/etc/resolv.conf"));
2292 ///
2293 /// assert!(!path.ends_with("/resolv.conf"));
2294 /// assert!(!path.ends_with("conf")); // use .extension() instead
2295 /// ```
2296 #[stable(feature = "rust1", since = "1.0.0")]
2297 #[must_use]
2298 pub fn ends_with<P: AsRef<Path>>(&self, child: P) -> bool {
2299 self._ends_with(child.as_ref())
2300 }
2301
2302 fn _ends_with(&self, child: &Path) -> bool {
2303 iter_after(self.components().rev(), child.components().rev()).is_some()
2304 }
2305
2306 /// Extracts the stem (non-extension) portion of [`self.file_name`].
2307 ///
2308 /// [`self.file_name`]: Path::file_name
2309 ///
2310 /// The stem is:
2311 ///
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 `.`
2316 ///
2317 /// # Examples
2318 ///
2319 /// ```
2320 /// use std::path::Path;
2321 ///
2322 /// assert_eq!("foo", Path::new("foo.rs").file_stem().unwrap());
2323 /// assert_eq!("foo.tar", Path::new("foo.tar.gz").file_stem().unwrap());
2324 /// ```
2325 ///
2326 /// # See Also
2327 /// This method is similar to [`Path::file_prefix`], which extracts the portion of the file name
2328 /// before the *first* `.`
2329 ///
2330 /// [`Path::file_prefix`]: Path::file_prefix
2331 ///
2332 #[stable(feature = "rust1", since = "1.0.0")]
2333 #[must_use]
2334 pub fn file_stem(&self) -> Option<&OsStr> {
2335 self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.or(after))
2336 }
2337
2338 /// Extracts the prefix of [`self.file_name`].
2339 ///
2340 /// The prefix is:
2341 ///
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 `.`
2347 ///
2348 /// [`self.file_name`]: Path::file_name
2349 ///
2350 /// # Examples
2351 ///
2352 /// ```
2353 /// # #![feature(path_file_prefix)]
2354 /// use std::path::Path;
2355 ///
2356 /// assert_eq!("foo", Path::new("foo.rs").file_prefix().unwrap());
2357 /// assert_eq!("foo", Path::new("foo.tar.gz").file_prefix().unwrap());
2358 /// ```
2359 ///
2360 /// # See Also
2361 /// This method is similar to [`Path::file_stem`], which extracts the portion of the file name
2362 /// before the *last* `.`
2363 ///
2364 /// [`Path::file_stem`]: Path::file_stem
2365 ///
2366 #[unstable(feature = "path_file_prefix", issue = "86319")]
2367 #[must_use]
2368 pub fn file_prefix(&self) -> Option<&OsStr> {
2369 self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before))
2370 }
2371
2372 /// Extracts the extension of [`self.file_name`], if possible.
2373 ///
2374 /// The extension is:
2375 ///
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 `.`
2380 ///
2381 /// [`self.file_name`]: Path::file_name
2382 ///
2383 /// # Examples
2384 ///
2385 /// ```
2386 /// use std::path::Path;
2387 ///
2388 /// assert_eq!("rs", Path::new("foo.rs").extension().unwrap());
2389 /// assert_eq!("gz", Path::new("foo.tar.gz").extension().unwrap());
2390 /// ```
2391 #[stable(feature = "rust1", since = "1.0.0")]
2392 #[must_use]
2393 pub fn extension(&self) -> Option<&OsStr> {
2394 self.file_name().map(rsplit_file_at_dot).and_then(|(before, after)| before.and(after))
2395 }
2396
2397 /// Creates an owned [`PathBuf`] with `path` adjoined to `self`.
2398 ///
2399 /// See [`PathBuf::push`] for more details on what it means to adjoin a path.
2400 ///
2401 /// # Examples
2402 ///
2403 /// ```
2404 /// use std::path::{Path, PathBuf};
2405 ///
2406 /// assert_eq!(Path::new("/etc").join("passwd"), PathBuf::from("/etc/passwd"));
2407 /// ```
2408 #[stable(feature = "rust1", since = "1.0.0")]
2409 #[must_use]
2410 pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
2411 self._join(path.as_ref())
2412 }
2413
2414 fn _join(&self, path: &Path) -> PathBuf {
2415 let mut buf = self.to_path_buf();
2416 buf.push(path);
2417 buf
2418 }
2419
2420 /// Creates an owned [`PathBuf`] like `self` but with the given file name.
2421 ///
2422 /// See [`PathBuf::set_file_name`] for more details.
2423 ///
2424 /// # Examples
2425 ///
2426 /// ```
2427 /// use std::path::{Path, PathBuf};
2428 ///
2429 /// let path = Path::new("/tmp/foo.txt");
2430 /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt"));
2431 ///
2432 /// let path = Path::new("/tmp");
2433 /// assert_eq!(path.with_file_name("var"), PathBuf::from("/var"));
2434 /// ```
2435 #[stable(feature = "rust1", since = "1.0.0")]
2436 #[must_use]
2437 pub fn with_file_name<S: AsRef<OsStr>>(&self, file_name: S) -> PathBuf {
2438 self._with_file_name(file_name.as_ref())
2439 }
2440
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);
2444 buf
2445 }
2446
2447 /// Creates an owned [`PathBuf`] like `self` but with the given extension.
2448 ///
2449 /// See [`PathBuf::set_extension`] for more details.
2450 ///
2451 /// # Examples
2452 ///
2453 /// ```
2454 /// use std::path::{Path, PathBuf};
2455 ///
2456 /// let path = Path::new("foo.rs");
2457 /// assert_eq!(path.with_extension("txt"), PathBuf::from("foo.txt"));
2458 ///
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"));
2463 /// ```
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())
2467 }
2468
2469 fn _with_extension(&self, extension: &OsStr) -> PathBuf {
2470 let mut buf = self.to_path_buf();
2471 buf.set_extension(extension);
2472 buf
2473 }
2474
2475 /// Produces an iterator over the [`Component`]s of the path.
2476 ///
2477 /// When parsing the path, there is a small amount of normalization:
2478 ///
2479 /// * Repeated separators are ignored, so `a/b` and `a//b` both have
2480 /// `a` and `b` as components.
2481 ///
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.
2486 ///
2487 /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
2488 ///
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`).
2492 ///
2493 /// # Examples
2494 ///
2495 /// ```
2496 /// use std::path::{Path, Component};
2497 /// use std::ffi::OsStr;
2498 ///
2499 /// let mut components = Path::new("/tmp/foo.txt").components();
2500 ///
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)
2505 /// ```
2506 ///
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());
2511 Components {
2512 path: self.as_u8_slice(),
2513 prefix,
2514 has_physical_root: has_physical_root(self.as_u8_slice(), prefix)
2515 || has_redox_scheme(self.as_u8_slice()),
2516 front: State::Prefix,
2517 back: State::Body,
2518 }
2519 }
2520
2521 /// Produces an iterator over the path's components viewed as [`OsStr`]
2522 /// slices.
2523 ///
2524 /// For more information about the particulars of how the path is separated
2525 /// into components, see [`components`].
2526 ///
2527 /// [`components`]: Path::components
2528 ///
2529 /// # Examples
2530 ///
2531 /// ```
2532 /// use std::path::{self, Path};
2533 /// use std::ffi::OsStr;
2534 ///
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)
2540 /// ```
2541 #[stable(feature = "rust1", since = "1.0.0")]
2542 #[inline]
2543 pub fn iter(&self) -> Iter<'_> {
2544 Iter { inner: self.components() }
2545 }
2546
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.
2551 ///
2552 /// [`Display`]: fmt::Display
2553 ///
2554 /// # Examples
2555 ///
2556 /// ```
2557 /// use std::path::Path;
2558 ///
2559 /// let path = Path::new("/tmp/foo.rs");
2560 ///
2561 /// println!("{}", path.display());
2562 /// ```
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"]
2566 #[inline]
2567 pub fn display(&self) -> Display<'_> {
2568 Display { path: self }
2569 }
2570
2571 /// Queries the file system to get information about a file, directory, etc.
2572 ///
2573 /// This function will traverse symbolic links to query information about the
2574 /// destination file.
2575 ///
2576 /// This is an alias to [`fs::metadata`].
2577 ///
2578 /// # Examples
2579 ///
2580 /// ```no_run
2581 /// use std::path::Path;
2582 ///
2583 /// let path = Path::new("/Minas/tirith");
2584 /// let metadata = path.metadata().expect("metadata call failed");
2585 /// println!("{:?}", metadata.file_type());
2586 /// ```
2587 #[stable(feature = "path_ext", since = "1.5.0")]
2588 #[inline]
2589 pub fn metadata(&self) -> io::Result<fs::Metadata> {
2590 fs::metadata(self)
2591 }
2592
2593 /// Queries the metadata about a file without following symlinks.
2594 ///
2595 /// This is an alias to [`fs::symlink_metadata`].
2596 ///
2597 /// # Examples
2598 ///
2599 /// ```no_run
2600 /// use std::path::Path;
2601 ///
2602 /// let path = Path::new("/Minas/tirith");
2603 /// let metadata = path.symlink_metadata().expect("symlink_metadata call failed");
2604 /// println!("{:?}", metadata.file_type());
2605 /// ```
2606 #[stable(feature = "path_ext", since = "1.5.0")]
2607 #[inline]
2608 pub fn symlink_metadata(&self) -> io::Result<fs::Metadata> {
2609 fs::symlink_metadata(self)
2610 }
2611
2612 /// Returns the canonical, absolute form of the path with all intermediate
2613 /// components normalized and symbolic links resolved.
2614 ///
2615 /// This is an alias to [`fs::canonicalize`].
2616 ///
2617 /// # Examples
2618 ///
2619 /// ```no_run
2620 /// use std::path::{Path, PathBuf};
2621 ///
2622 /// let path = Path::new("/foo/test/../test/bar.rs");
2623 /// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs"));
2624 /// ```
2625 #[stable(feature = "path_ext", since = "1.5.0")]
2626 #[inline]
2627 pub fn canonicalize(&self) -> io::Result<PathBuf> {
2628 fs::canonicalize(self)
2629 }
2630
2631 /// Reads a symbolic link, returning the file that the link points to.
2632 ///
2633 /// This is an alias to [`fs::read_link`].
2634 ///
2635 /// # Examples
2636 ///
2637 /// ```no_run
2638 /// use std::path::Path;
2639 ///
2640 /// let path = Path::new("/laputa/sky_castle.rs");
2641 /// let path_link = path.read_link().expect("read_link call failed");
2642 /// ```
2643 #[stable(feature = "path_ext", since = "1.5.0")]
2644 #[inline]
2645 pub fn read_link(&self) -> io::Result<PathBuf> {
2646 fs::read_link(self)
2647 }
2648
2649 /// Returns an iterator over the entries within a directory.
2650 ///
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.
2653 ///
2654 /// This is an alias to [`fs::read_dir`].
2655 ///
2656 /// # Examples
2657 ///
2658 /// ```no_run
2659 /// use std::path::Path;
2660 ///
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());
2665 /// }
2666 /// }
2667 /// ```
2668 #[stable(feature = "path_ext", since = "1.5.0")]
2669 #[inline]
2670 pub fn read_dir(&self) -> io::Result<fs::ReadDir> {
2671 fs::read_dir(self)
2672 }
2673
2674 /// Returns `true` if the path points at an existing entity.
2675 ///
2676 /// This function will traverse symbolic links to query information about the
2677 /// destination file.
2678 ///
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`.
2681 ///
2682 /// # Examples
2683 ///
2684 /// ```no_run
2685 /// use std::path::Path;
2686 /// assert!(!Path::new("does_not_exist.txt").exists());
2687 /// ```
2688 ///
2689 /// # See Also
2690 ///
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")]
2694 #[must_use]
2695 #[inline]
2696 pub fn exists(&self) -> bool {
2697 fs::metadata(self).is_ok()
2698 }
2699
2700 /// Returns `Ok(true)` if the path points at an existing entity.
2701 ///
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)`.
2704 ///
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.)
2708 ///
2709 /// # Examples
2710 ///
2711 /// ```no_run
2712 /// #![feature(path_try_exists)]
2713 ///
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());
2717 /// ```
2718 // FIXME: stabilization should modify documentation of `exists()` to recommend this method
2719 // instead.
2720 #[unstable(feature = "path_try_exists", issue = "83186")]
2721 #[inline]
2722 pub fn try_exists(&self) -> io::Result<bool> {
2723 fs::try_exists(self)
2724 }
2725
2726 /// Returns `true` if the path exists on disk and is pointing at a regular file.
2727 ///
2728 /// This function will traverse symbolic links to query information about the
2729 /// destination file.
2730 ///
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`.
2733 ///
2734 /// # Examples
2735 ///
2736 /// ```no_run
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);
2740 /// ```
2741 ///
2742 /// # See Also
2743 ///
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`].
2747 ///
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")]
2754 #[must_use]
2755 pub fn is_file(&self) -> bool {
2756 fs::metadata(self).map(|m| m.is_file()).unwrap_or(false)
2757 }
2758
2759 /// Returns `true` if the path exists on disk and is pointing at a directory.
2760 ///
2761 /// This function will traverse symbolic links to query information about the
2762 /// destination file.
2763 ///
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`.
2766 ///
2767 /// # Examples
2768 ///
2769 /// ```no_run
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);
2773 /// ```
2774 ///
2775 /// # See Also
2776 ///
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")]
2781 #[must_use]
2782 pub fn is_dir(&self) -> bool {
2783 fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
2784 }
2785
2786 /// Returns `true` if the path exists on disk and is pointing at a symbolic link.
2787 ///
2788 /// This function will not traverse symbolic links.
2789 /// In case of a broken symbolic link this will also return true.
2790 ///
2791 /// If you cannot access the directory containing the file, e.g., because of a
2792 /// permission error, this will return false.
2793 ///
2794 /// # Examples
2795 ///
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;
2800 ///
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);
2805 /// ```
2806 ///
2807 /// # See Also
2808 ///
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`].
2812 #[must_use]
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)
2816 }
2817
2818 /// Converts a [`Box<Path>`](Box) into a [`PathBuf`] without copying or
2819 /// allocating.
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) }
2826 }
2827 }
2828
2829 #[stable(feature = "rust1", since = "1.0.0")]
2830 impl AsRef<OsStr> for Path {
2831 #[inline]
2832 fn as_ref(&self) -> &OsStr {
2833 &self.inner
2834 }
2835 }
2836
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)
2841 }
2842 }
2843
2844 /// Helper struct for safely printing paths with [`format!`] and `{}`.
2845 ///
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.
2851 ///
2852 /// # Examples
2853 ///
2854 /// ```
2855 /// use std::path::Path;
2856 ///
2857 /// let path = Path::new("/tmp/foo.rs");
2858 ///
2859 /// println!("{}", path.display());
2860 /// ```
2861 ///
2862 /// [`Display`]: fmt::Display
2863 /// [`format!`]: crate::format
2864 #[stable(feature = "rust1", since = "1.0.0")]
2865 pub struct Display<'a> {
2866 path: &'a Path,
2867 }
2868
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)
2873 }
2874 }
2875
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)
2880 }
2881 }
2882
2883 #[stable(feature = "rust1", since = "1.0.0")]
2884 impl cmp::PartialEq for Path {
2885 #[inline]
2886 fn eq(&self, other: &Path) -> bool {
2887 self.components() == other.components()
2888 }
2889 }
2890
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) {
2896 Some(prefix) => {
2897 prefix.hash(h);
2898 prefix.len()
2899 }
2900 None => 0,
2901 };
2902 let bytes = &bytes[prefix_len..];
2903
2904 let mut component_start = 0;
2905 let mut bytes_hashed = 0;
2906
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];
2911 h.write(to_hash);
2912 bytes_hashed += to_hash.len();
2913 }
2914
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,
2919 _ => 1,
2920 };
2921 }
2922 }
2923
2924 if component_start < bytes.len() {
2925 let to_hash = &bytes[component_start..];
2926 h.write(to_hash);
2927 bytes_hashed += to_hash.len();
2928 }
2929
2930 h.write_usize(bytes_hashed);
2931 }
2932 }
2933
2934 #[stable(feature = "rust1", since = "1.0.0")]
2935 impl cmp::Eq for Path {}
2936
2937 #[stable(feature = "rust1", since = "1.0.0")]
2938 impl cmp::PartialOrd for Path {
2939 #[inline]
2940 fn partial_cmp(&self, other: &Path) -> Option<cmp::Ordering> {
2941 Some(compare_components(self.components(), other.components()))
2942 }
2943 }
2944
2945 #[stable(feature = "rust1", since = "1.0.0")]
2946 impl cmp::Ord for Path {
2947 #[inline]
2948 fn cmp(&self, other: &Path) -> cmp::Ordering {
2949 compare_components(self.components(), other.components())
2950 }
2951 }
2952
2953 #[stable(feature = "rust1", since = "1.0.0")]
2954 impl AsRef<Path> for Path {
2955 #[inline]
2956 fn as_ref(&self) -> &Path {
2957 self
2958 }
2959 }
2960
2961 #[stable(feature = "rust1", since = "1.0.0")]
2962 impl AsRef<Path> for OsStr {
2963 #[inline]
2964 fn as_ref(&self) -> &Path {
2965 Path::new(self)
2966 }
2967 }
2968
2969 #[stable(feature = "cow_os_str_as_ref_path", since = "1.8.0")]
2970 impl AsRef<Path> for Cow<'_, OsStr> {
2971 #[inline]
2972 fn as_ref(&self) -> &Path {
2973 Path::new(self)
2974 }
2975 }
2976
2977 #[stable(feature = "rust1", since = "1.0.0")]
2978 impl AsRef<Path> for OsString {
2979 #[inline]
2980 fn as_ref(&self) -> &Path {
2981 Path::new(self)
2982 }
2983 }
2984
2985 #[stable(feature = "rust1", since = "1.0.0")]
2986 impl AsRef<Path> for str {
2987 #[inline]
2988 fn as_ref(&self) -> &Path {
2989 Path::new(self)
2990 }
2991 }
2992
2993 #[stable(feature = "rust1", since = "1.0.0")]
2994 impl AsRef<Path> for String {
2995 #[inline]
2996 fn as_ref(&self) -> &Path {
2997 Path::new(self)
2998 }
2999 }
3000
3001 #[stable(feature = "rust1", since = "1.0.0")]
3002 impl AsRef<Path> for PathBuf {
3003 #[inline]
3004 fn as_ref(&self) -> &Path {
3005 self
3006 }
3007 }
3008
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>;
3013 #[inline]
3014 fn into_iter(self) -> Iter<'a> {
3015 self.iter()
3016 }
3017 }
3018
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>;
3023 #[inline]
3024 fn into_iter(self) -> Iter<'a> {
3025 self.iter()
3026 }
3027 }
3028
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 {
3033 #[inline]
3034 fn eq(&self, other: &$rhs) -> bool {
3035 <Path as PartialEq>::eq(self, other)
3036 }
3037 }
3038
3039 #[stable(feature = "partialeq_path", since = "1.6.0")]
3040 impl<'a, 'b> PartialEq<$lhs> for $rhs {
3041 #[inline]
3042 fn eq(&self, other: &$lhs) -> bool {
3043 <Path as PartialEq>::eq(self, other)
3044 }
3045 }
3046
3047 #[stable(feature = "cmp_path", since = "1.8.0")]
3048 impl<'a, 'b> PartialOrd<$rhs> for $lhs {
3049 #[inline]
3050 fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
3051 <Path as PartialOrd>::partial_cmp(self, other)
3052 }
3053 }
3054
3055 #[stable(feature = "cmp_path", since = "1.8.0")]
3056 impl<'a, 'b> PartialOrd<$lhs> for $rhs {
3057 #[inline]
3058 fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
3059 <Path as PartialOrd>::partial_cmp(self, other)
3060 }
3061 }
3062 };
3063 }
3064
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);
3070
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 {
3075 #[inline]
3076 fn eq(&self, other: &$rhs) -> bool {
3077 <Path as PartialEq>::eq(self, other.as_ref())
3078 }
3079 }
3080
3081 #[stable(feature = "cmp_path", since = "1.8.0")]
3082 impl<'a, 'b> PartialEq<$lhs> for $rhs {
3083 #[inline]
3084 fn eq(&self, other: &$lhs) -> bool {
3085 <Path as PartialEq>::eq(self.as_ref(), other)
3086 }
3087 }
3088
3089 #[stable(feature = "cmp_path", since = "1.8.0")]
3090 impl<'a, 'b> PartialOrd<$rhs> for $lhs {
3091 #[inline]
3092 fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
3093 <Path as PartialOrd>::partial_cmp(self, other.as_ref())
3094 }
3095 }
3096
3097 #[stable(feature = "cmp_path", since = "1.8.0")]
3098 impl<'a, 'b> PartialOrd<$lhs> for $rhs {
3099 #[inline]
3100 fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
3101 <Path as PartialOrd>::partial_cmp(self.as_ref(), other)
3102 }
3103 }
3104 };
3105 }
3106
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);
3121
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)
3127 }
3128 }
3129
3130 #[stable(since = "1.7.0", feature = "strip_prefix")]
3131 impl Error for StripPrefixError {
3132 #[allow(deprecated)]
3133 fn description(&self) -> &str {
3134 "prefix not found"
3135 }
3136 }