kernel/fs/path.rs
1// This is taken and heavily modified of `unix_path`
2// which is modified from the standard library.
3// source: https://gitlab.com/SnejUgal/unix_path
4//
5// Permission is hereby granted, free of charge, to any
6// person obtaining a copy of this software and associated
7// documentation files (the "Software"), to deal in the
8// Software without restriction, including without
9// limitation the rights to use, copy, modify, merge,
10// publish, distribute, sublicense, and/or sell copies of
11// the Software, and to permit persons to whom the Software
12// is furnished to do so, subject to the following
13// conditions:
14
15// The above copyright notice and this permission notice
16// shall be included in all copies or substantial portions
17// of the Software.
18
19// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
20// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
21// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
23// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
26// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27// DEALINGS IN THE SOFTWARE.
28
29//! A library for parsing, manipulating Paths that follow unix style conventions.
30//!
31//! This is similar to how the standard library's [`Path`] works, but may have less features.
32//!
33//! For simplicity, this uses `str` and `String` instead of `OsStr` and `OsString`.
34//! Makes it much easier to work with.
35use core::{
36 borrow::Borrow,
37 cmp, fmt,
38 hash::{Hash, Hasher},
39 iter::{self, FusedIterator},
40 ops::{self, Deref},
41 str::FromStr,
42};
43
44use alloc::{
45 borrow::{Cow, ToOwned},
46 boxed::Box,
47 rc::Rc,
48 string::{String, ToString},
49 sync::Arc,
50};
51
52/// use unix paths separator
53pub const SEPARATOR: char = '/';
54
55pub fn is_separator(c: char) -> bool {
56 c == SEPARATOR
57}
58
59fn is_separator_byte(c: u8) -> bool {
60 c == SEPARATOR as u8
61}
62
63// Iterate through `iter` while it matches `prefix`; return `None` if `prefix`
64// is not a prefix of `iter`, otherwise return `Some(iter_after_prefix)` giving
65// `iter` after having exhausted `prefix`.
66fn iter_after<'a, 'b, I, J>(mut iter: I, mut prefix: J) -> Option<I>
67where
68 I: Iterator<Item = Component<'a>> + Clone,
69 J: Iterator<Item = Component<'b>>,
70{
71 loop {
72 let mut iter_next = iter.clone();
73 match (iter_next.next(), prefix.next()) {
74 (Some(ref x), Some(ref y)) if x == y => (),
75 (Some(_), Some(_)) => return None,
76 (Some(_), None) => return Some(iter),
77 (None, None) => return Some(iter),
78 (None, Some(_)) => return None,
79 }
80 iter = iter_next;
81 }
82}
83
84/// Check if the first char is `/`
85fn has_root(path: &str) -> bool {
86 !path.is_empty() && path.as_bytes()[0] == b'/'
87}
88
89/// Component parsing works by a double-ended state machine; the cursors at the
90/// front and back of the path each keep track of what parts of the path have
91/// been consumed so far.
92///
93/// Going front to back, a path is made up of a prefix, a starting
94/// directory component, and a body (of normal components)
95#[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
96enum State {
97 Prefix = 0,
98 StartDir = 1, // / or . or nothing
99 Body = 2, // foo/bar/baz
100 Done = 3,
101}
102
103/// A single component of a path.
104///
105/// A `Component` roughly corresponds to a substring between path separators
106/// (`/`).
107///
108/// This `enum` is created by iterating over [`Components`], which in turn is
109/// created by the [`components`][`Path::components`] method on [`Path`].
110///
111/// # Examples
112///
113/// ```rust
114/// let path = Path::new("/tmp/foo/bar.txt");
115/// let components = path.components().collect::<Vec<_>>();
116/// assert_eq!(&components, &[
117/// Component::RootDir,
118/// Component::Normal("tmp".as_ref()),
119/// Component::Normal("foo".as_ref()),
120/// Component::Normal("bar.txt".as_ref()),
121/// ]);
122/// ```
123#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
124pub enum Component<'a> {
125 /// The root directory component, appears after any prefix and before anything else.
126 ///
127 /// It represents a separator that designates that a path starts from root.
128 RootDir,
129
130 /// A reference to the current directory, i.e., `.`.
131 CurDir,
132
133 /// A reference to the parent directory, i.e., `..`.
134 ParentDir,
135
136 /// A normal component, e.g., `a` and `b` in `a/b`.
137 ///
138 /// This variant is the most common one, it represents references to files
139 /// or directories.
140 Normal(&'a str),
141}
142
143impl<'a> Component<'a> {
144 /// Extracts the underlying `str`.
145 ///
146 /// # Examples
147 ///
148 /// ```
149 /// let path = Path::new("./tmp/foo/bar.txt");
150 /// let components: Vec<_> = path.components().map(|comp| comp.as_str()).collect();
151 /// assert_eq!(&components, &[".", "tmp", "foo", "bar.txt"]);
152 /// ```
153 pub fn as_str(self) -> &'a str {
154 match self {
155 Component::RootDir => "/",
156 Component::CurDir => ".",
157 Component::ParentDir => "..",
158 Component::Normal(path) => path,
159 }
160 }
161}
162
163impl AsRef<str> for Component<'_> {
164 fn as_ref(&self) -> &str {
165 self.as_str()
166 }
167}
168
169impl AsRef<Path> for Component<'_> {
170 fn as_ref(&self) -> &Path {
171 self.as_str().as_ref()
172 }
173}
174
175/// An iterator over the [`Component`]s of a [`Path`].
176///
177/// This `struct` is created by the [`components`](Path::components) method on [`Path`].
178/// See its documentation for more.
179///
180/// # Examples
181///
182/// ```
183/// let path = Path::new("/tmp/foo/bar.txt");
184///
185/// for component in path.components() {
186/// println!("{:?}", component);
187/// }
188/// ```
189#[derive(Clone)]
190pub struct Components<'a> {
191 // The path left to parse components from
192 path: &'a str,
193
194 // true if path *physically* has a root separator;.
195 has_root: bool,
196
197 // The iterator is double-ended, and these two states keep track of what has
198 // been produced from either end
199 front: State,
200 back: State,
201}
202
203/// An iterator over the [`Component`]s of a [`Path`], as [`str`] slices.
204///
205/// This `struct` is created by the [`iter`] method on [`Path`].
206/// See its documentation for more.
207#[derive(Clone)]
208pub struct Iter<'a> {
209 inner: Components<'a>,
210}
211
212impl fmt::Debug for Components<'_> {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 struct DebugHelper<'a>(&'a Path);
215
216 impl fmt::Debug for DebugHelper<'_> {
217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
218 f.debug_list().entries(self.0.components()).finish()
219 }
220 }
221
222 f.debug_tuple("Components")
223 .field(&DebugHelper(self.as_path()))
224 .finish()
225 }
226}
227
228impl<'a> Components<'a> {
229 // Given the iteration so far, how much of the pre-State::Body path is left?
230 #[inline]
231 fn len_before_body(&self) -> usize {
232 let root = if self.front <= State::StartDir && self.has_root {
233 1
234 } else {
235 0
236 };
237 let cur_dir = if self.front <= State::StartDir && self.include_cur_dir() {
238 1
239 } else {
240 0
241 };
242 root + cur_dir
243 }
244
245 // is the iteration complete?
246 #[inline]
247 fn finished(&self) -> bool {
248 self.front == State::Done || self.back == State::Done || self.front > self.back
249 }
250
251 /// Extracts a slice corresponding to the portion of the path remaining for iteration.
252 ///
253 /// # Examples
254 ///
255 /// ```
256 /// let mut components = Path::new("/tmp/foo/bar.txt").components();
257 /// components.next();
258 /// components.next();
259 ///
260 /// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
261 /// ```
262 pub fn as_path(&self) -> &'a Path {
263 let mut comps = self.clone();
264 if comps.front == State::Body {
265 comps.trim_left();
266 }
267 if comps.back == State::Body {
268 comps.trim_right();
269 }
270 Path::new(comps.path)
271 }
272
273 /// Is the *original* path rooted?
274 fn has_root(&self) -> bool {
275 self.has_root
276 }
277
278 /// Should the normalized path include a leading . ?
279 fn include_cur_dir(&self) -> bool {
280 if self.has_root() {
281 return false;
282 }
283 let mut iter = self.path[..].chars();
284 match (iter.next(), iter.next()) {
285 (Some('.'), None) => true,
286 (Some('.'), Some(c)) => is_separator(c),
287 _ => false,
288 }
289 }
290
291 // parse a given byte sequence into the corresponding path component
292 fn parse_single_component<'b>(&self, comp: &'b str) -> Option<Component<'b>> {
293 match comp {
294 "." => None, // . components are normalized away, except at
295 // the beginning of a path, which is treated
296 // separately via `include_cur_dir`
297 ".." => Some(Component::ParentDir),
298 "" => None,
299 _ => Some(Component::Normal(comp)),
300 }
301 }
302
303 // parse a component from the left, saying how many bytes to consume to
304 // remove the component
305 fn parse_next_component(&self) -> (usize, Option<Component<'a>>) {
306 debug_assert!(self.front == State::Body);
307 let (extra, comp) = match self.path.chars().position(is_separator) {
308 None => (0, self.path),
309 Some(i) => (1, &self.path[..i]),
310 };
311 (comp.len() + extra, self.parse_single_component(comp))
312 }
313
314 // parse a component from the right, saying how many bytes to consume to
315 // remove the component
316 fn parse_next_component_back(&self) -> (usize, Option<Component<'a>>) {
317 debug_assert!(self.back == State::Body);
318 let start = self.len_before_body();
319 // FIXME: should be `chars`, but its easier this way
320 let (extra, comp) = match self.path[start..].bytes().rposition(is_separator_byte) {
321 None => (0, &self.path[start..]),
322 Some(i) => (1, &self.path[start + i + 1..]),
323 };
324 (comp.len() + extra, self.parse_single_component(comp))
325 }
326
327 // trim away repeated separators (i.e., empty components) on the left
328 fn trim_left(&mut self) {
329 while !self.path.is_empty() {
330 let (size, comp) = self.parse_next_component();
331 if comp.is_some() {
332 return;
333 } else {
334 self.path = &self.path[size..];
335 }
336 }
337 }
338
339 // trim away repeated separators (i.e., empty components) on the right
340 fn trim_right(&mut self) {
341 while self.path.len() > self.len_before_body() {
342 let (size, comp) = self.parse_next_component_back();
343 if comp.is_some() {
344 return;
345 } else {
346 self.path = &self.path[..self.path.len() - size];
347 }
348 }
349 }
350
351 pub fn peek(&self) -> Option<Component<'a>> {
352 // this is a lie, but it works, the clone cost isn't very high, so should be okay
353 self.clone().next()
354 }
355}
356
357impl AsRef<Path> for Components<'_> {
358 fn as_ref(&self) -> &Path {
359 self.as_path()
360 }
361}
362
363impl AsRef<str> for Components<'_> {
364 fn as_ref(&self) -> &str {
365 self.as_path().as_str()
366 }
367}
368
369impl fmt::Debug for Iter<'_> {
370 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
371 struct DebugHelper<'a>(&'a Path);
372
373 impl fmt::Debug for DebugHelper<'_> {
374 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
375 f.debug_list().entries(self.0.iter()).finish()
376 }
377 }
378
379 f.debug_tuple("Iter")
380 .field(&DebugHelper(self.as_path()))
381 .finish()
382 }
383}
384
385impl<'a> Iter<'a> {
386 /// Extracts a slice corresponding to the portion of the path remaining for iteration.
387 ///
388 /// # Examples
389 ///
390 /// ```
391 /// let mut iter = Path::new("/tmp/foo/bar.txt").iter();
392 /// iter.next();
393 /// iter.next();
394 ///
395 /// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
396 /// ```
397 pub fn as_path(&self) -> &'a Path {
398 self.inner.as_path()
399 }
400}
401
402impl AsRef<Path> for Iter<'_> {
403 fn as_ref(&self) -> &Path {
404 self.as_path()
405 }
406}
407
408impl AsRef<str> for Iter<'_> {
409 fn as_ref(&self) -> &str {
410 self.as_path().as_str()
411 }
412}
413
414impl<'a> Iterator for Iter<'a> {
415 type Item = &'a str;
416
417 fn next(&mut self) -> Option<Self::Item> {
418 self.inner.next().map(Component::as_str)
419 }
420}
421
422impl<'a> DoubleEndedIterator for Iter<'a> {
423 fn next_back(&mut self) -> Option<Self::Item> {
424 self.inner.next_back().map(Component::as_str)
425 }
426}
427
428impl FusedIterator for Iter<'_> {}
429
430impl<'a> Iterator for Components<'a> {
431 type Item = Component<'a>;
432
433 fn next(&mut self) -> Option<Component<'a>> {
434 while !self.finished() {
435 match self.front {
436 State::Prefix => {
437 self.front = State::StartDir;
438 }
439 State::StartDir => {
440 self.front = State::Body;
441 if self.has_root {
442 debug_assert!(!self.path.is_empty());
443 self.path = &self.path[1..];
444 return Some(Component::RootDir);
445 } else if self.include_cur_dir() {
446 debug_assert!(!self.path.is_empty());
447 self.path = &self.path[1..];
448 return Some(Component::CurDir);
449 }
450 }
451 State::Body if !self.path.is_empty() => {
452 let (size, comp) = self.parse_next_component();
453 self.path = &self.path[size..];
454 if comp.is_some() {
455 return comp;
456 }
457 }
458 State::Body => {
459 self.front = State::Done;
460 }
461 State::Done => unreachable!(),
462 }
463 }
464 None
465 }
466}
467
468impl<'a> DoubleEndedIterator for Components<'a> {
469 fn next_back(&mut self) -> Option<Component<'a>> {
470 while !self.finished() {
471 match self.back {
472 State::Body if self.path.len() > self.len_before_body() => {
473 let (size, comp) = self.parse_next_component_back();
474 self.path = &self.path[..self.path.len() - size];
475 if comp.is_some() {
476 return comp;
477 }
478 }
479 State::Body => {
480 self.back = State::StartDir;
481 }
482 State::StartDir => {
483 self.back = State::Prefix;
484 if self.has_root {
485 self.path = &self.path[..self.path.len() - 1];
486 return Some(Component::RootDir);
487 } else if self.include_cur_dir() {
488 self.path = &self.path[..self.path.len() - 1];
489 return Some(Component::CurDir);
490 }
491 }
492 State::Prefix => {
493 self.back = State::Done;
494 return None;
495 }
496 State::Done => unreachable!(),
497 }
498 }
499 None
500 }
501}
502
503impl FusedIterator for Components<'_> {}
504
505impl<'a> cmp::PartialEq for Components<'a> {
506 fn eq(&self, other: &Components<'a>) -> bool {
507 Iterator::eq(self.clone(), other.clone())
508 }
509}
510
511impl cmp::Eq for Components<'_> {}
512
513impl<'a> cmp::PartialOrd for Components<'a> {
514 fn partial_cmp(&self, other: &Components<'a>) -> Option<cmp::Ordering> {
515 Some(self.cmp(other))
516 }
517}
518
519impl cmp::Ord for Components<'_> {
520 fn cmp(&self, other: &Self) -> cmp::Ordering {
521 Iterator::cmp(self.clone(), other.clone())
522 }
523}
524
525/// An iterator over [`Path`] and its ancestors.
526///
527/// This `struct` is created by the [`Path::ancestors`] method on [`Path`].
528/// See its documentation for more.
529///
530/// # Examples
531///
532/// ```
533/// let path = Path::new("/foo/bar");
534///
535/// for ancestor in path.ancestors() {
536/// println!("{:?}", ancestor);
537/// }
538/// ```
539#[derive(Copy, Clone, Debug)]
540pub struct Ancestors<'a> {
541 next: Option<&'a Path>,
542}
543
544impl<'a> Iterator for Ancestors<'a> {
545 type Item = &'a Path;
546
547 fn next(&mut self) -> Option<Self::Item> {
548 let next = self.next;
549 self.next = next.and_then(Path::parent);
550 next
551 }
552}
553
554impl FusedIterator for Ancestors<'_> {}
555
556/// An owned, mutable path (akin to `String`).
557///
558/// This type provides methods like [`PathBuf::push`] that mutate
559/// the path in place. It also implements `Deref` to [`Path`], meaning that
560/// all methods on [`Path`] slices are available on `PathBuf` values as well.
561///
562/// More details about the overall approach can be found in
563/// the [crate documentation](index.html).
564///
565/// # Examples
566///
567/// You can use [`PathBuf::push`] to build up a [`PathBuf`] from
568/// components:
569///
570/// ```
571/// let mut path = PathBuf::new();
572///
573/// path.push("/");
574/// path.push("feel");
575/// path.push("the");
576/// ```
577///
578/// However, [`PathBuf::push`] is best used for dynamic situations. This is a better way
579/// to do this when you know all of the components ahead of time:
580///
581/// ```
582/// let path: PathBuf = ["/", "feel", "the.force"].iter().collect();
583/// ```
584///
585/// We can still do better than this! Since these are all strings, we can use
586/// [`From::from`]:
587///
588/// ```
589/// let path = PathBuf::from(r"/feel/the.force");
590/// ```
591///
592/// Which method works best depends on what kind of situation you're in.
593#[derive(Clone)]
594pub struct PathBuf {
595 inner: String,
596}
597
598impl PathBuf {
599 /// Allocates an empty [`PathBuf`].
600 ///
601 /// # Examples
602 ///
603 /// ```
604 /// let path = PathBuf::new();
605 /// ```
606 pub fn new() -> PathBuf {
607 PathBuf {
608 inner: String::new(),
609 }
610 }
611
612 /// Creates a new [`PathBuf`] with a given capacity used to create the
613 /// internal [`String`]. See [`String::with_capacity`].
614 ///
615 /// # Examples
616 ///
617 /// ```
618 /// let mut path = PathBuf::with_capacity(10);
619 /// let capacity = path.capacity();
620 ///
621 /// // This push is done without reallocating
622 /// path.push("/");
623 ///
624 /// assert_eq!(capacity, path.capacity());
625 /// ```
626 pub fn with_capacity(capacity: usize) -> PathBuf {
627 PathBuf {
628 inner: String::with_capacity(capacity),
629 }
630 }
631
632 /// Coerces to a [`Path`] slice.
633 ///
634 /// [`Path`]: struct.Path.html
635 ///
636 /// # Examples
637 ///
638 /// ```
639 /// let p = PathBuf::from("/test");
640 /// assert_eq!(Path::new("/test"), p.as_path());
641 /// ```
642 pub fn as_path(&self) -> &Path {
643 self
644 }
645
646 /// Extends `self` with `path`.
647 ///
648 /// If `path` is absolute, it replaces the current path.
649 ///
650 /// # Examples
651 ///
652 /// Pushing a relative path extends the existing path:
653 ///
654 /// ```
655 /// let mut path = PathBuf::from("/tmp");
656 /// path.push("file.bk");
657 /// assert_eq!(path, PathBuf::from("/tmp/file.bk"));
658 /// ```
659 ///
660 /// Pushing an absolute path replaces the existing path:
661 ///
662 /// ```
663 /// let mut path = PathBuf::from("/tmp");
664 /// path.push("/etc");
665 /// assert_eq!(path, PathBuf::from("/etc"));
666 /// ```
667 pub fn push<P: AsRef<Path>>(&mut self, path: P) {
668 self._push(path.as_ref())
669 }
670
671 fn _push(&mut self, path: &Path) {
672 // in general, a separator is needed if the rightmost byte is not a separator
673 let need_sep = self
674 .as_str()
675 .chars()
676 .last()
677 .map(|c| !is_separator(c))
678 .unwrap_or(false);
679
680 // absolute `path` replaces `self`
681 if path.is_absolute() || path.has_root() {
682 self.inner.clear();
683 } else if need_sep {
684 self.inner.push(SEPARATOR);
685 }
686
687 self.inner.push_str(path.as_str());
688 }
689
690 /// Truncates `self` to [`self.parent`].
691 ///
692 /// Returns `false` and does nothing if [`self.parent`] is `None`.
693 /// Otherwise, returns `true`.
694 ///
695 /// [`self.parent`]: struct.PathBuf.html#method.parent
696 ///
697 /// # Examples
698 ///
699 /// ```
700 /// let mut p = PathBuf::from("/test/test.rs");
701 ///
702 /// p.pop();
703 /// assert_eq!(Path::new("/test"), p);
704 /// p.pop();
705 /// assert_eq!(Path::new("/"), p);
706 /// ```
707 pub fn pop(&mut self) -> bool {
708 match self.parent().map(|p| p.as_str().len()) {
709 Some(len) => {
710 self.inner.truncate(len);
711 true
712 }
713 None => false,
714 }
715 }
716
717 /// Updates [`self.file_name`] to `file_name`.
718 ///
719 /// If [`self.file_name`] was `None`, this is equivalent to pushing
720 /// `file_name`.
721 ///
722 /// Otherwise it is equivalent to calling [`pop`] and then pushing
723 /// `file_name`. The new path will be a sibling of the original path.
724 /// (That is, it will have the same parent.)
725 ///
726 /// [`self.file_name`]: PathBuf
727 /// [`pop`]: PathBuf::pop
728 ///
729 /// # Examples
730 ///
731 /// ```
732 /// let mut buf = PathBuf::from("/");
733 /// assert!(buf.file_name() == None);
734 /// buf.set_file_name("bar");
735 /// assert!(buf == PathBuf::from("/bar"));
736 /// assert!(buf.file_name().is_some());
737 /// buf.set_file_name("baz.txt");
738 /// assert!(buf == PathBuf::from("/baz.txt"));
739 /// ```
740 pub fn set_file_name<S: AsRef<str>>(&mut self, file_name: S) {
741 self._set_file_name(file_name.as_ref())
742 }
743
744 fn _set_file_name(&mut self, file_name: &str) {
745 if self.file_name().is_some() {
746 let popped = self.pop();
747 debug_assert!(popped);
748 }
749 self.push(file_name);
750 }
751
752 /// Consumes the `PathBuf`, yielding its internal `String` storage.
753 ///
754 /// # Examples
755 ///
756 /// ```
757 /// let p = PathBuf::from("/the/head");
758 /// let bytes = p.into_string();
759 /// ```
760 pub fn into_string(self) -> String {
761 self.inner
762 }
763
764 /// Converts this `PathBuf` into a boxed [`Path`].
765 ///
766 /// [`Path`]: struct.Path.html
767 pub fn into_boxed_path(self) -> Box<Path> {
768 let rw = Box::into_raw(self.inner.into_boxed_str()) as *mut Path;
769 unsafe { Box::from_raw(rw) }
770 }
771
772 /// Invokes `capacity` on the underlying instance of `String`.
773 pub fn capacity(&self) -> usize {
774 self.inner.capacity()
775 }
776
777 /// Invokes `clear` on the underlying instance of `String`.
778 pub fn clear(&mut self) {
779 self.inner.clear()
780 }
781
782 /// Invokes `reserve` on the underlying instance of `String`.
783 pub fn reserve(&mut self, additional: usize) {
784 self.inner.reserve(additional)
785 }
786
787 /// Invokes `reserve_exact` on the underlying instance of `String`.
788 pub fn reserve_exact(&mut self, additional: usize) {
789 self.inner.reserve_exact(additional)
790 }
791
792 /// Invokes `shrink_to_fit` on the underlying instance of `String`.
793 pub fn shrink_to_fit(&mut self) {
794 self.inner.shrink_to_fit()
795 }
796
797 /// Invokes `shrink_to` on the underlying instance of `String`.
798 pub fn shrink_to(&mut self, min_capacity: usize) {
799 self.inner.shrink_to(min_capacity)
800 }
801}
802
803impl From<&Path> for Box<Path> {
804 fn from(path: &Path) -> Box<Path> {
805 path.to_path_buf().into_boxed_path()
806 }
807}
808
809impl From<Cow<'_, Path>> for Box<Path> {
810 #[inline]
811 fn from(cow: Cow<'_, Path>) -> Box<Path> {
812 match cow {
813 Cow::Borrowed(path) => Box::from(path),
814 Cow::Owned(path) => Box::from(path),
815 }
816 }
817}
818
819impl From<PathBuf> for Box<Path> {
820 /// Converts a `PathBuf` into a `Box<Path>`
821 ///
822 /// This conversion currently should not allocate memory,
823 /// but this behavior is not guaranteed in all future versions.
824 fn from(p: PathBuf) -> Self {
825 p.into_boxed_path()
826 }
827}
828
829impl Clone for Box<Path> {
830 #[inline]
831 fn clone(&self) -> Self {
832 self.to_path_buf().into_boxed_path()
833 }
834}
835
836impl<T: ?Sized + AsRef<str>> From<&T> for PathBuf {
837 fn from(s: &T) -> Self {
838 PathBuf::from(s.as_ref().to_string())
839 }
840}
841
842impl From<String> for PathBuf {
843 /// Converts a [`String`] into a [`PathBuf`]
844 ///
845 /// This conversion does not allocate or copy memory.
846 #[inline]
847 fn from(s: String) -> Self {
848 PathBuf { inner: s }
849 }
850}
851
852impl From<PathBuf> for String {
853 /// Converts a [`PathBuf`] into a [`String`]
854 ///
855 /// This conversion does not allocate or copy memory.
856 fn from(path_buf: PathBuf) -> Self {
857 path_buf.inner
858 }
859}
860
861impl FromStr for PathBuf {
862 type Err = core::convert::Infallible;
863
864 fn from_str(s: &str) -> Result<Self, Self::Err> {
865 Ok(PathBuf::from(s))
866 }
867}
868
869impl<P: AsRef<Path>> iter::FromIterator<P> for PathBuf {
870 fn from_iter<I: IntoIterator<Item = P>>(iter: I) -> PathBuf {
871 let mut buf = PathBuf::new();
872 buf.extend(iter);
873 buf
874 }
875}
876
877impl<P: AsRef<Path>> iter::Extend<P> for PathBuf {
878 fn extend<I: IntoIterator<Item = P>>(&mut self, iter: I) {
879 iter.into_iter().for_each(move |p| self.push(p.as_ref()));
880 }
881}
882
883impl fmt::Debug for PathBuf {
884 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
885 fmt::Debug::fmt(&**self, formatter)
886 }
887}
888
889impl ops::Deref for PathBuf {
890 type Target = Path;
891 #[inline]
892 fn deref(&self) -> &Path {
893 Path::new(&self.inner)
894 }
895}
896
897impl Borrow<Path> for PathBuf {
898 fn borrow(&self) -> &Path {
899 self.deref()
900 }
901}
902
903impl Default for PathBuf {
904 fn default() -> Self {
905 PathBuf::new()
906 }
907}
908
909impl<'a> From<&'a Path> for Cow<'a, Path> {
910 #[inline]
911 fn from(s: &'a Path) -> Cow<'a, Path> {
912 Cow::Borrowed(s)
913 }
914}
915
916impl<'a> From<PathBuf> for Cow<'a, Path> {
917 #[inline]
918 fn from(s: PathBuf) -> Cow<'a, Path> {
919 Cow::Owned(s)
920 }
921}
922
923impl<'a> From<&'a PathBuf> for Cow<'a, Path> {
924 #[inline]
925 fn from(p: &'a PathBuf) -> Cow<'a, Path> {
926 Cow::Borrowed(p.as_path())
927 }
928}
929
930impl<'a> From<Cow<'a, Path>> for PathBuf {
931 #[inline]
932 fn from(p: Cow<'a, Path>) -> Self {
933 p.into_owned()
934 }
935}
936
937impl From<PathBuf> for Arc<Path> {
938 /// Converts a `PathBuf` into an `Arc` by moving the `PathBuf` data into a new `Arc` buffer.
939 #[inline]
940 fn from(s: PathBuf) -> Arc<Path> {
941 let arc: Arc<str> = Arc::from(s.into_string());
942 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) }
943 }
944}
945
946impl From<&Path> for Arc<Path> {
947 /// Converts a `Path` into an `Arc` by copying the `Path` data into a new `Arc` buffer.
948 #[inline]
949 fn from(s: &Path) -> Arc<Path> {
950 let arc: Arc<str> = Arc::from(s.as_str());
951 unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) }
952 }
953}
954
955impl From<PathBuf> for Rc<Path> {
956 /// Converts a `PathBuf` into an `Rc` by moving the `PathBuf` data into a new `Rc` buffer.
957 #[inline]
958 fn from(s: PathBuf) -> Rc<Path> {
959 let rc: Rc<str> = Rc::from(s.into_string());
960 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) }
961 }
962}
963
964impl From<&Path> for Rc<Path> {
965 /// Converts a `Path` into an `Rc` by copying the `Path` data into a new `Rc` buffer.
966 #[inline]
967 fn from(s: &Path) -> Rc<Path> {
968 let rc: Rc<str> = Rc::from(s.as_str());
969 unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) }
970 }
971}
972
973impl ToOwned for Path {
974 type Owned = PathBuf;
975 fn to_owned(&self) -> PathBuf {
976 self.to_path_buf()
977 }
978}
979
980impl cmp::PartialEq for PathBuf {
981 fn eq(&self, other: &PathBuf) -> bool {
982 self.components() == other.components()
983 }
984}
985
986impl Hash for PathBuf {
987 fn hash<H: Hasher>(&self, h: &mut H) {
988 self.as_path().hash(h)
989 }
990}
991
992impl cmp::Eq for PathBuf {}
993
994impl cmp::PartialOrd for PathBuf {
995 fn partial_cmp(&self, other: &PathBuf) -> Option<cmp::Ordering> {
996 Some(self.cmp(other))
997 }
998}
999
1000impl cmp::Ord for PathBuf {
1001 fn cmp(&self, other: &PathBuf) -> cmp::Ordering {
1002 self.components().cmp(other.components())
1003 }
1004}
1005
1006impl AsRef<str> for PathBuf {
1007 fn as_ref(&self) -> &str {
1008 &self.inner[..]
1009 }
1010}
1011
1012/// A slice of a path (akin to `str`).
1013///
1014/// This type supports a number of operations for inspecting a path, including
1015/// breaking the path into its components (separated by `/` ), extracting the
1016/// file name, determining whether the path is absolute, and so on.
1017///
1018/// This is an *unsized* type, meaning that it must always be used behind a
1019/// pointer like `&` or `Box`. For an owned version of this type,
1020/// see [`PathBuf`].
1021///
1022/// More details about the overall approach can be found in
1023/// the [crate documentation](index.html).
1024///
1025/// # Examples
1026///
1027/// ```
1028/// let path = Path::new("./foo/bar.txt");
1029///
1030/// let parent = path.parent();
1031/// assert_eq!(parent, Some(Path::new("./foo")));
1032/// ```
1033#[repr(transparent)]
1034pub struct Path {
1035 inner: str,
1036}
1037
1038/// An error returned from [`Path::strip_prefix`][`strip_prefix`] if the prefix
1039/// was not found.
1040///
1041/// This `struct` is created by the [`strip_prefix`] method on [`Path`].
1042/// See its documentation for more.
1043///
1044/// [`strip_prefix`]: struct.Path.html#method.strip_prefix
1045/// [`Path`]: struct.Path.html
1046#[derive(Debug, Clone, PartialEq, Eq)]
1047pub struct StripPrefixError(());
1048
1049impl Path {
1050 /// Directly wraps a string slice as a `Path` slice.
1051 ///
1052 /// This is a cost-free conversion.
1053 ///
1054 /// # Examples
1055 ///
1056 /// ```
1057 /// Path::new("foo.txt");
1058 /// ```
1059 ///
1060 /// You can create `Path`s from `String`s, or even other `Path`s:
1061 ///
1062 /// ```
1063 /// let string = String::from("foo.txt");
1064 /// let from_string = Path::new(&string);
1065 /// let from_path = Path::new(&from_string);
1066 /// assert_eq!(from_string, from_path);
1067 /// ```
1068 pub fn new<S: AsRef<str> + ?Sized>(s: &S) -> &Path {
1069 unsafe { &*(s.as_ref() as *const str as *const Path) }
1070 }
1071
1072 /// Yields the underlying bytes.
1073 ///
1074 /// # Examples
1075 ///
1076 /// ```
1077 /// let os_str = Path::new("foo.txt").as_str();
1078 /// assert_eq!(os_str, "foo.txt");
1079 /// ```
1080 pub fn as_str(&self) -> &str {
1081 &self.inner
1082 }
1083
1084 /// Yields a `&str` slice if the `Path` is valid unicode.
1085 ///
1086 /// This conversion may entail doing a check for UTF-8 validity.
1087 /// Note that validation is performed because non-UTF-8 strings are
1088 /// perfectly valid for some OS.
1089 ///
1090 /// # Examples
1091 ///
1092 /// ```
1093 /// let path = Path::new("foo.txt");
1094 /// assert_eq!(path.to_str(), Some("foo.txt"));
1095 /// ```
1096 pub fn to_str(&self) -> Option<&str> {
1097 Some(self.as_str())
1098 }
1099
1100 /// Converts a `Path` to a `Cow<str>`.
1101 ///
1102 /// Any non-Unicode sequences are replaced with
1103 /// `U+FFFD REPLACEMENT CHARACTER`.
1104 ///
1105 ///
1106 /// # Examples
1107 ///
1108 /// Calling `to_string_lossy` on a `Path` with valid unicode:
1109 ///
1110 /// ```
1111 /// let path = Path::new("foo.txt");
1112 /// assert_eq!(path.to_string_lossy(), "foo.txt");
1113 /// ```
1114 ///
1115 /// Had `path` contained invalid unicode, the `to_string_lossy` call might
1116 /// have returned `"fo�.txt"`.
1117 pub fn to_string_lossy(&self) -> Cow<'_, str> {
1118 Cow::Borrowed(&self.inner)
1119 }
1120
1121 /// Converts a `Path` to an owned [`PathBuf`].
1122 ///
1123 /// [`PathBuf`]: struct.PathBuf.html
1124 ///
1125 /// # Examples
1126 ///
1127 /// ```
1128 /// let path_buf = Path::new("foo.txt").to_path_buf();
1129 /// assert_eq!(path_buf, PathBuf::from("foo.txt"));
1130 /// ```
1131 pub fn to_path_buf(&self) -> PathBuf {
1132 PathBuf::from(&self.inner)
1133 }
1134
1135 /// Returns `true` if the `Path` is absolute, i.e., if it is independent of
1136 /// the current directory.
1137 ///
1138 /// A path is absolute if it starts with the root, so `is_absolute` and
1139 /// [`has_root`] are equivalent.
1140 ///
1141 /// # Examples
1142 ///
1143 /// ```
1144 /// assert!(!Path::new("foo.txt").is_absolute());
1145 /// ```
1146 pub fn is_absolute(&self) -> bool {
1147 self.has_root()
1148 }
1149
1150 /// Returns `true` if the `Path` is relative, i.e., not absolute.
1151 ///
1152 /// See [`is_absolute`]'s documentation for more details.
1153 ///
1154 /// # Examples
1155 ///
1156 /// ```
1157 /// assert!(Path::new("foo.txt").is_relative());
1158 /// ```
1159 ///
1160 /// [`is_absolute`]: #method.is_absolute
1161 pub fn is_relative(&self) -> bool {
1162 !self.is_absolute()
1163 }
1164
1165 /// Returns `true` if the `Path` has a root.
1166 ///
1167 /// A path has a root if it begins with `/`.
1168 ///
1169 /// # Examples
1170 ///
1171 /// ```
1172 /// assert!(Path::new("/etc/passwd").has_root());
1173 /// ```
1174 pub fn has_root(&self) -> bool {
1175 self.components().has_root()
1176 }
1177 /// Checks if the path ends with a separator.
1178 ///
1179 /// This function checks if the last character of the path string is a separator character.
1180 /// If the path is empty, it returns `false`.
1181 ///
1182 /// # Returns
1183 ///
1184 /// * `true` if the path ends with a separator.
1185 /// * `false` if the path does not end with a separator or if the path is empty.
1186 ///
1187 /// # Examples
1188 ///
1189 /// ```
1190 /// use your_module::Path;
1191 ///
1192 /// let p = Path::new("/some/path/");
1193 /// assert_eq!(p.has_last_separator(), true);
1194 ///
1195 /// let p = Path::new("/some/path");
1196 /// assert_eq!(p.has_last_separator(), false);
1197 /// ```
1198 pub fn has_last_separator(&self) -> bool {
1199 self.as_str()
1200 .chars()
1201 .last()
1202 .map(is_separator)
1203 .unwrap_or(false)
1204 }
1205
1206 /// Checks if the path is the root directory.
1207 ///
1208 /// This function compares the path string with "/", the root directory.
1209 /// If the path is "/", it returns `true`. For any other path, it returns `false`.
1210 ///
1211 /// # Returns
1212 ///
1213 /// * `true` if the path is the root directory ("/").
1214 /// * `false` if the path is not the root directory.
1215 ///
1216 /// # Examples
1217 ///
1218 /// ```
1219 /// use your_module::Path;
1220 ///
1221 /// let p = Path::new("/");
1222 /// assert_eq!(p.is_root(), true);
1223 ///
1224 /// let p = Path::new("/some/path");
1225 /// assert_eq!(p.is_root(), false);
1226 /// ```
1227 pub fn is_root(&self) -> bool {
1228 self.as_str() == "/"
1229 }
1230
1231 /// Checks if the path is empty.
1232 ///
1233 /// This function checks if the path string is empty. If the path is an empty string, it returns `true`.
1234 /// For any non-empty path, it returns `false`.
1235 ///
1236 /// # Returns
1237 ///
1238 /// * `true` if the path is an empty string.
1239 /// * `false` if the path is not an empty string.
1240 ///
1241 /// # Examples
1242 ///
1243 /// ```
1244 /// use your_module::Path;
1245 ///
1246 /// let p = Path::new("");
1247 /// assert_eq!(p.is_empty(), true);
1248 ///
1249 /// let p = Path::new("/some/path");
1250 /// assert_eq!(p.is_empty(), false);
1251 /// ```
1252 pub fn is_empty(&self) -> bool {
1253 self.as_str().is_empty()
1254 }
1255
1256 /// Returns the `Path` without its final component, if there is one.
1257 ///
1258 /// Returns `None` if the path terminates in a root or prefix.
1259 ///
1260 /// # Examples
1261 ///
1262 /// ```
1263 /// let path = Path::new("/foo/bar");
1264 /// let parent = path.parent().unwrap();
1265 /// assert_eq!(parent, Path::new("/foo"));
1266 ///
1267 /// let grand_parent = parent.parent().unwrap();
1268 /// assert_eq!(grand_parent, Path::new("/"));
1269 /// assert_eq!(grand_parent.parent(), None);
1270 /// ```
1271 pub fn parent(&self) -> Option<&Path> {
1272 let mut comps = self.components();
1273 let comp = comps.next_back();
1274 comp.and_then(|p| match p {
1275 Component::Normal(_) | Component::CurDir | Component::ParentDir => {
1276 Some(comps.as_path())
1277 }
1278 _ => None,
1279 })
1280 }
1281
1282 /// Produces an iterator over `Path` and its ancestors.
1283 ///
1284 /// The iterator will yield the `Path` that is returned if the [`parent`] method is used zero
1285 /// or more times. That means, the iterator will yield `&self`, `&self.parent().unwrap()`,
1286 /// `&self.parent().unwrap().parent().unwrap()` and so on. If the [`parent`] method returns
1287 /// `None`, the iterator will do likewise. The iterator will always yield at least one value,
1288 /// namely `&self`.
1289 ///
1290 /// # Examples
1291 ///
1292 /// ```
1293 /// let mut ancestors = Path::new("/foo/bar").ancestors();
1294 /// assert_eq!(ancestors.next(), Some(Path::new("/foo/bar")));
1295 /// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
1296 /// assert_eq!(ancestors.next(), Some(Path::new("/")));
1297 /// assert_eq!(ancestors.next(), None);
1298 /// ```
1299 ///
1300 /// [`parent`]: struct.Path.html#method.parent
1301 pub fn ancestors(&self) -> Ancestors<'_> {
1302 Ancestors { next: Some(self) }
1303 }
1304
1305 /// Returns the final component of the `Path`, if there is one.
1306 ///
1307 /// If the path is a normal file, this is the file name. If it's the path of a directory, this
1308 /// is the directory name.
1309 ///
1310 /// Returns `None` if the path terminates in `..`.
1311 ///
1312 /// # Examples
1313 ///
1314 /// ```
1315 /// assert_eq!(Some("bin"), Path::new("/usr/bin/").file_name());
1316 /// assert_eq!(Some("foo.txt"), Path::new("tmp/foo.txt").file_name());
1317 /// assert_eq!(Some("foo.txt"), Path::new("foo.txt/.").file_name());
1318 /// assert_eq!(Some("foo.txt"), Path::new("foo.txt/.//").file_name());
1319 /// assert_eq!(None, Path::new("foo.txt/..").file_name());
1320 /// assert_eq!(None, Path::new("/").file_name());
1321 /// ```
1322 pub fn file_name(&self) -> Option<&str> {
1323 self.components().next_back().and_then(|p| match p {
1324 Component::Normal(p) => Some(p),
1325 _ => None,
1326 })
1327 }
1328
1329 /// Returns a path that, when joined onto `base`, yields `self`.
1330 ///
1331 /// # Errors
1332 ///
1333 /// If `base` is not a prefix of `self` (i.e., [`starts_with`]
1334 /// returns `false`), returns `Err`.
1335 ///
1336 /// [`starts_with`]: #method.starts_with
1337 ///
1338 /// # Examples
1339 ///
1340 /// ```
1341 /// let path = Path::new("/test/haha/foo.txt");
1342 ///
1343 /// assert_eq!(path.strip_prefix("/"), Ok(Path::new("test/haha/foo.txt")));
1344 /// assert_eq!(path.strip_prefix("/test"), Ok(Path::new("haha/foo.txt")));
1345 /// assert_eq!(path.strip_prefix("/test/"), Ok(Path::new("haha/foo.txt")));
1346 /// assert_eq!(path.strip_prefix("/test/haha/foo.txt"), Ok(Path::new("")));
1347 /// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
1348 /// assert_eq!(path.strip_prefix("test").is_ok(), false);
1349 /// assert_eq!(path.strip_prefix("/haha").is_ok(), false);
1350 ///
1351 /// let prefix = PathBuf::from("/test/");
1352 /// assert_eq!(path.strip_prefix(prefix), Ok(Path::new("haha/foo.txt")));
1353 /// ```
1354 pub fn strip_prefix<P>(&self, base: P) -> Result<&Path, StripPrefixError>
1355 where
1356 P: AsRef<Path>,
1357 {
1358 self._strip_prefix(base.as_ref())
1359 }
1360
1361 fn _strip_prefix(&self, base: &Path) -> Result<&Path, StripPrefixError> {
1362 iter_after(self.components(), base.components())
1363 .map(|c| c.as_path())
1364 .ok_or(StripPrefixError(()))
1365 }
1366
1367 /// Determines whether `base` is a prefix of `self`.
1368 ///
1369 /// Only considers whole path components to match.
1370 ///
1371 /// # Examples
1372 ///
1373 /// ```
1374 /// let path = Path::new("/etc/passwd");
1375 ///
1376 /// assert!(path.starts_with("/etc"));
1377 /// assert!(path.starts_with("/etc/"));
1378 /// assert!(path.starts_with("/etc/passwd"));
1379 /// assert!(path.starts_with("/etc/passwd/"));
1380 ///
1381 /// assert!(!path.starts_with("/e"));
1382 /// ```
1383 pub fn starts_with<P: AsRef<Path>>(&self, base: P) -> bool {
1384 self._starts_with(base.as_ref())
1385 }
1386
1387 fn _starts_with(&self, base: &Path) -> bool {
1388 iter_after(self.components(), base.components()).is_some()
1389 }
1390
1391 /// Determines whether `child` is a suffix of `self`.
1392 ///
1393 /// Only considers whole path components to match.
1394 ///
1395 /// # Examples
1396 ///
1397 /// ```
1398 /// let path = Path::new("/etc/passwd");
1399 ///
1400 /// assert!(path.ends_with("passwd"));
1401 /// ```
1402 pub fn ends_with<P: AsRef<Path>>(&self, child: P) -> bool {
1403 self._ends_with(child.as_ref())
1404 }
1405
1406 fn _ends_with(&self, child: &Path) -> bool {
1407 iter_after(self.components().rev(), child.components().rev()).is_some()
1408 }
1409
1410 /// Creates an owned [`PathBuf`] with `path` adjoined to `self`.
1411 ///
1412 /// See [`PathBuf::push`] for more details on what it means to adjoin a path.
1413 ///
1414 /// [`PathBuf`]: struct.PathBuf.html
1415 /// [`PathBuf::push`]: struct.PathBuf.html#method.push
1416 ///
1417 /// # Examples
1418 ///
1419 /// ```
1420 /// assert_eq!(Path::new("/etc").join("passwd"), PathBuf::from("/etc/passwd"));
1421 /// ```
1422 #[must_use]
1423 pub fn join<P: AsRef<Path>>(&self, path: P) -> PathBuf {
1424 self._join(path.as_ref())
1425 }
1426
1427 fn _join(&self, path: &Path) -> PathBuf {
1428 let mut buf = self.to_path_buf();
1429 buf.push(path);
1430 buf
1431 }
1432
1433 /// Creates an owned [`PathBuf`] like `self` but with the given file name.
1434 ///
1435 /// See [`PathBuf::set_file_name`] for more details.
1436 ///
1437 /// [`PathBuf`]: struct.PathBuf.html
1438 /// [`PathBuf::set_file_name`]: struct.PathBuf.html#method.set_file_name
1439 ///
1440 /// # Examples
1441 ///
1442 /// ```
1443 /// let path = Path::new("/tmp/foo.txt");
1444 /// assert_eq!(path.with_file_name("bar.txt"), PathBuf::from("/tmp/bar.txt"));
1445 ///
1446 /// let path = Path::new("/tmp");
1447 /// assert_eq!(path.with_file_name("var"), PathBuf::from("/var"));
1448 /// ```
1449 pub fn with_file_name<S: AsRef<str>>(&self, file_name: S) -> PathBuf {
1450 self._with_file_name(file_name.as_ref())
1451 }
1452
1453 fn _with_file_name(&self, file_name: &str) -> PathBuf {
1454 let mut buf = self.to_path_buf();
1455 buf.set_file_name(file_name);
1456 buf
1457 }
1458
1459 /// Produces an iterator over the [`Component`]s of the path.
1460 ///
1461 /// When parsing the path, there is a small amount of normalization:
1462 ///
1463 /// * Repeated separators are ignored, so `a/b` and `a//b` both have
1464 /// `a` and `b` as components.
1465 ///
1466 /// * Occurrences of `.` are normalized away, except if they are at the
1467 /// beginning of the path. For example, `a/./b`, `a/b/`, `a/b/.` and
1468 /// `a/b` all have `a` and `b` as components, but `./a/b` starts with
1469 /// an additional [`Component::CurDir`] component.
1470 ///
1471 /// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
1472 ///
1473 /// Note that no other normalization takes place; in particular, `a/c`
1474 /// and `a/b/../c` are distinct, to account for the possibility that `b`
1475 /// is a symbolic link (so its parent isn't `a`).
1476 ///
1477 /// # Examples
1478 ///
1479 /// ```
1480 /// let mut components = Path::new("/tmp/foo.txt").components();
1481 ///
1482 /// assert_eq!(components.next(), Some(Component::RootDir));
1483 /// assert_eq!(components.next(), Some(Component::Normal("tmp")));
1484 /// assert_eq!(components.next(), Some(Component::Normal("foo.txt")));
1485 /// assert_eq!(components.next(), None)
1486 /// ```
1487 pub fn components(&self) -> Components<'_> {
1488 Components {
1489 path: &self.inner,
1490 has_root: has_root(&self.inner),
1491 front: State::Prefix,
1492 back: State::Body,
1493 }
1494 }
1495
1496 /// Produces an iterator over the path's components viewed as `str`
1497 /// slices.
1498 ///
1499 /// For more information about the particulars of how the path is separated
1500 /// into components, see [`components`].
1501 ///
1502 /// [`components`]: #method.components
1503 ///
1504 /// # Examples
1505 ///
1506 /// ```
1507 /// let mut it = Path::new("/tmp/foo.txt").iter();
1508 /// assert_eq!(it.next(), Some("/"));
1509 /// assert_eq!(it.next(), Some("tmp"));
1510 /// assert_eq!(it.next(), Some("foo.txt"));
1511 /// assert_eq!(it.next(), None)
1512 /// ```
1513 pub fn iter(&self) -> Iter<'_> {
1514 Iter {
1515 inner: self.components(),
1516 }
1517 }
1518
1519 /// Returns a newtype that implements Display for safely printing paths
1520 /// that may contain non-Unicode data.
1521 pub fn display(&self) -> Display<'_> {
1522 Display { path: self }
1523 }
1524}
1525
1526impl AsRef<str> for Path {
1527 fn as_ref(&self) -> &str {
1528 &self.inner
1529 }
1530}
1531
1532impl fmt::Debug for Path {
1533 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1534 fmt::Debug::fmt(&self.inner, formatter)
1535 }
1536}
1537
1538impl cmp::PartialEq for Path {
1539 fn eq(&self, other: &Path) -> bool {
1540 self.components().eq(other.components())
1541 }
1542}
1543
1544impl Hash for Path {
1545 fn hash<H: Hasher>(&self, h: &mut H) {
1546 for component in self.components() {
1547 component.hash(h);
1548 }
1549 }
1550}
1551
1552impl cmp::Eq for Path {}
1553
1554impl cmp::PartialOrd for Path {
1555 fn partial_cmp(&self, other: &Path) -> Option<cmp::Ordering> {
1556 Some(self.cmp(other))
1557 }
1558}
1559
1560impl cmp::Ord for Path {
1561 fn cmp(&self, other: &Path) -> cmp::Ordering {
1562 self.components().cmp(other.components())
1563 }
1564}
1565
1566impl AsRef<Path> for Path {
1567 fn as_ref(&self) -> &Path {
1568 self
1569 }
1570}
1571
1572impl AsRef<Path> for str {
1573 #[inline]
1574 fn as_ref(&self) -> &Path {
1575 Path::new(self)
1576 }
1577}
1578
1579impl AsRef<Path> for String {
1580 fn as_ref(&self) -> &Path {
1581 Path::new(self)
1582 }
1583}
1584
1585impl AsRef<Path> for PathBuf {
1586 #[inline]
1587 fn as_ref(&self) -> &Path {
1588 self
1589 }
1590}
1591
1592impl<'a> IntoIterator for &'a PathBuf {
1593 type Item = &'a str;
1594 type IntoIter = Iter<'a>;
1595 fn into_iter(self) -> Iter<'a> {
1596 self.iter()
1597 }
1598}
1599
1600impl<'a> IntoIterator for &'a Path {
1601 type Item = &'a str;
1602 type IntoIter = Iter<'a>;
1603 fn into_iter(self) -> Iter<'a> {
1604 self.iter()
1605 }
1606}
1607
1608macro_rules! impl_cmp {
1609 ($lhs:ty, $rhs: ty) => {
1610 impl<'a, 'b> PartialEq<$rhs> for $lhs {
1611 #[inline]
1612 fn eq(&self, other: &$rhs) -> bool {
1613 <Path as PartialEq>::eq(self, other)
1614 }
1615 }
1616
1617 impl<'a, 'b> PartialEq<$lhs> for $rhs {
1618 #[inline]
1619 fn eq(&self, other: &$lhs) -> bool {
1620 <Path as PartialEq>::eq(self, other)
1621 }
1622 }
1623
1624 impl<'a, 'b> PartialOrd<$rhs> for $lhs {
1625 #[inline]
1626 fn partial_cmp(&self, other: &$rhs) -> Option<cmp::Ordering> {
1627 <Path as PartialOrd>::partial_cmp(self, other)
1628 }
1629 }
1630
1631 impl<'a, 'b> PartialOrd<$lhs> for $rhs {
1632 #[inline]
1633 fn partial_cmp(&self, other: &$lhs) -> Option<cmp::Ordering> {
1634 <Path as PartialOrd>::partial_cmp(self, other)
1635 }
1636 }
1637 };
1638}
1639
1640impl_cmp!(PathBuf, Path);
1641impl_cmp!(PathBuf, &'a Path);
1642impl_cmp!(Cow<'a, Path>, Path);
1643impl_cmp!(Cow<'a, Path>, &'b Path);
1644impl_cmp!(Cow<'a, Path>, PathBuf);
1645
1646impl fmt::Display for StripPrefixError {
1647 #[allow(deprecated, deprecated_in_future)]
1648 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1649 "prefix not found".fmt(f)
1650 }
1651}
1652
1653pub struct Display<'a> {
1654 path: &'a Path,
1655}
1656
1657impl fmt::Debug for Display<'_> {
1658 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1659 fmt::Debug::fmt(&self.path, formatter)
1660 }
1661}
1662
1663impl fmt::Display for Display<'_> {
1664 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1665 fmt::Display::fmt(&self.path.as_str(), formatter)
1666 }
1667}