typed_path/typed/utf8/
iter.rs

1use core::fmt;
2use core::iter::FusedIterator;
3
4use crate::common::{Utf8Ancestors, Utf8Iter};
5use crate::typed::Utf8TypedPath;
6use crate::unix::Utf8UnixEncoding;
7use crate::windows::Utf8WindowsEncoding;
8
9/// An iterator over the [`Utf8TypedComponent`]s of a [`Utf8TypedPath`], as [`str`] slices.
10///
11/// This `struct` is created by the [`iter`] method on [`Utf8TypedPath`].
12/// See its documentation for more.
13///
14/// [`iter`]: Utf8TypedPath::iter
15/// [`Utf8TypedComponent`]: crate::Utf8TypedComponent
16#[derive(Clone)]
17pub enum Utf8TypedIter<'a> {
18    Unix(Utf8Iter<'a, Utf8UnixEncoding>),
19    Windows(Utf8Iter<'a, Utf8WindowsEncoding>),
20}
21
22impl Utf8TypedIter<'_> {
23    /// Extracts a slice corresponding to the portion of the path remaining for iteration.
24    ///
25    /// # Examples
26    ///
27    /// ```
28    /// use typed_path::Utf8TypedPath;
29    ///
30    /// let mut iter = Utf8TypedPath::derive("/tmp/foo/bar.txt").iter();
31    /// iter.next();
32    /// iter.next();
33    ///
34    /// assert_eq!(Utf8TypedPath::derive("foo/bar.txt"), iter.to_path());
35    /// ```
36    pub fn to_path(&self) -> Utf8TypedPath<'_> {
37        match self {
38            Self::Unix(it) => Utf8TypedPath::Unix(it.as_path()),
39            Self::Windows(it) => Utf8TypedPath::Windows(it.as_path()),
40        }
41    }
42
43    /// Returns reference to the underlying str slice represented by this iterator.
44    pub fn as_str(&self) -> &str {
45        impl_typed_fn!(self, as_ref)
46    }
47}
48
49impl fmt::Debug for Utf8TypedIter<'_> {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        struct DebugHelper<'a>(Utf8TypedPath<'a>);
52
53        impl fmt::Debug for DebugHelper<'_> {
54            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55                f.debug_list().entries(self.0.iter()).finish()
56            }
57        }
58
59        f.debug_tuple(stringify!(Utf8TypedIter))
60            .field(&DebugHelper(self.to_path()))
61            .finish()
62    }
63}
64
65impl AsRef<[u8]> for Utf8TypedIter<'_> {
66    #[inline]
67    fn as_ref(&self) -> &[u8] {
68        self.as_str().as_bytes()
69    }
70}
71
72impl AsRef<str> for Utf8TypedIter<'_> {
73    #[inline]
74    fn as_ref(&self) -> &str {
75        self.as_str()
76    }
77}
78
79impl<'a> Iterator for Utf8TypedIter<'a> {
80    type Item = &'a str;
81
82    #[inline]
83    fn next(&mut self) -> Option<Self::Item> {
84        match self {
85            Self::Unix(it) => it.next(),
86            Self::Windows(it) => it.next(),
87        }
88    }
89}
90
91impl DoubleEndedIterator for Utf8TypedIter<'_> {
92    #[inline]
93    fn next_back(&mut self) -> Option<Self::Item> {
94        match self {
95            Self::Unix(it) => it.next_back(),
96            Self::Windows(it) => it.next_back(),
97        }
98    }
99}
100
101impl FusedIterator for Utf8TypedIter<'_> {}
102
103/// An iterator over [`Utf8TypedPath`] and its ancestors.
104///
105/// This `struct` is created by the [`ancestors`] method on [`Utf8TypedPath`].
106/// See its documentation for more.
107///
108/// # Examples
109///
110/// ```
111/// use typed_path::Utf8TypedPath;
112///
113/// let path = Utf8TypedPath::derive("/foo/bar");
114///
115/// for ancestor in path.ancestors() {
116///     println!("{}", ancestor);
117/// }
118/// ```
119///
120/// [`ancestors`]: Utf8TypedPath::ancestors
121#[derive(Copy, Clone, Debug)]
122pub enum Utf8TypedAncestors<'a> {
123    Unix(Utf8Ancestors<'a, Utf8UnixEncoding>),
124    Windows(Utf8Ancestors<'a, Utf8WindowsEncoding>),
125}
126
127impl<'a> Iterator for Utf8TypedAncestors<'a> {
128    type Item = Utf8TypedPath<'a>;
129
130    #[inline]
131    fn next(&mut self) -> Option<Self::Item> {
132        match self {
133            Self::Unix(it) => it.next().map(Utf8TypedPath::Unix),
134            Self::Windows(it) => it.next().map(Utf8TypedPath::Windows),
135        }
136    }
137}
138
139impl FusedIterator for Utf8TypedAncestors<'_> {}