typed_path/unix/utf8/
components.rs

1mod component;
2
3use core::{cmp, fmt, iter};
4
5pub use component::*;
6
7use crate::unix::UnixComponents;
8use crate::{private, Components, Utf8Components, Utf8Encoding, Utf8Path};
9
10#[derive(Clone)]
11pub struct Utf8UnixComponents<'a> {
12    inner: UnixComponents<'a>,
13}
14
15impl<'a> Utf8UnixComponents<'a> {
16    pub(crate) fn new(path: &'a str) -> Self {
17        Self {
18            inner: UnixComponents::new(path.as_bytes()),
19        }
20    }
21
22    /// Extracts a slice corresponding to the portion of the path remaining for iteration.
23    ///
24    /// # Examples
25    ///
26    /// ```
27    /// use typed_path::{Utf8Path, Utf8UnixEncoding};
28    ///
29    /// // NOTE: A path cannot be created on its own without a defined encoding
30    /// let mut components = Utf8Path::<Utf8UnixEncoding>::new("/tmp/foo/bar.txt").components();
31    /// components.next();
32    /// components.next();
33    ///
34    /// assert_eq!(Utf8Path::<Utf8UnixEncoding>::new("foo/bar.txt"), components.as_path());
35    /// ```
36    pub fn as_path<T>(&self) -> &'a Utf8Path<T>
37    where
38        T: Utf8Encoding,
39    {
40        Utf8Path::new(self.as_str())
41    }
42}
43
44impl private::Sealed for Utf8UnixComponents<'_> {}
45
46impl<'a> Utf8Components<'a> for Utf8UnixComponents<'a> {
47    type Component = Utf8UnixComponent<'a>;
48
49    fn as_str(&self) -> &'a str {
50        // NOTE: We know that the internal byte representation is UTF-8 compliant as we ensure that
51        //       the only input provided is UTF-8 and no modifications are made with non-UTF-8 bytes
52        unsafe { core::str::from_utf8_unchecked(self.inner.as_bytes()) }
53    }
54
55    fn is_absolute(&self) -> bool {
56        self.inner.is_absolute()
57    }
58
59    fn has_root(&self) -> bool {
60        self.inner.has_root()
61    }
62}
63
64impl AsRef<[u8]> for Utf8UnixComponents<'_> {
65    #[inline]
66    fn as_ref(&self) -> &[u8] {
67        self.as_str().as_bytes()
68    }
69}
70
71impl AsRef<str> for Utf8UnixComponents<'_> {
72    #[inline]
73    fn as_ref(&self) -> &str {
74        self.as_str()
75    }
76}
77
78impl<T> AsRef<Utf8Path<T>> for Utf8UnixComponents<'_>
79where
80    T: Utf8Encoding,
81{
82    #[inline]
83    fn as_ref(&self) -> &Utf8Path<T> {
84        Utf8Path::new(self.as_str())
85    }
86}
87
88impl fmt::Debug for Utf8UnixComponents<'_> {
89    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90        struct DebugHelper<'a>(Utf8UnixComponents<'a>);
91
92        impl fmt::Debug for DebugHelper<'_> {
93            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94                f.debug_list().entries(self.0.clone()).finish()
95            }
96        }
97
98        f.debug_tuple("Utf8WindowsComponents")
99            .field(&DebugHelper(self.clone()))
100            .finish()
101    }
102}
103
104impl<'a> Iterator for Utf8UnixComponents<'a> {
105    type Item = <Self as Utf8Components<'a>>::Component;
106
107    fn next(&mut self) -> Option<Self::Item> {
108        self.inner
109            .next()
110            .map(|c| unsafe { Utf8UnixComponent::from_utf8_unchecked(&c) })
111    }
112}
113
114impl DoubleEndedIterator for Utf8UnixComponents<'_> {
115    fn next_back(&mut self) -> Option<Self::Item> {
116        self.inner
117            .next_back()
118            .map(|c| unsafe { Utf8UnixComponent::from_utf8_unchecked(&c) })
119    }
120}
121
122impl iter::FusedIterator for Utf8UnixComponents<'_> {}
123
124impl cmp::PartialEq for Utf8UnixComponents<'_> {
125    #[inline]
126    fn eq(&self, other: &Self) -> bool {
127        PartialEq::eq(&self.inner, &other.inner)
128    }
129}
130
131impl cmp::Eq for Utf8UnixComponents<'_> {}
132
133impl cmp::PartialOrd for Utf8UnixComponents<'_> {
134    #[inline]
135    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
136        Some(self.cmp(other))
137    }
138}
139
140impl cmp::Ord for Utf8UnixComponents<'_> {
141    #[inline]
142    fn cmp(&self, other: &Self) -> cmp::Ordering {
143        Ord::cmp(&self.inner, &other.inner)
144    }
145}