typed_path/windows/utf8/
components.rs1mod component;
2
3use core::{cmp, fmt, iter};
4
5pub use component::*;
6
7use crate::windows::WindowsComponents;
8use crate::{private, Components, Utf8Components, Utf8Encoding, Utf8Path};
9
10#[derive(Clone)]
12pub struct Utf8WindowsComponents<'a> {
13 inner: WindowsComponents<'a>,
14}
15
16impl<'a> Utf8WindowsComponents<'a> {
17 pub(crate) fn new(path: &'a str) -> Self {
18 Self {
19 inner: WindowsComponents::new(path.as_bytes()),
20 }
21 }
22
23 pub fn as_path<T>(&self) -> &'a Utf8Path<T>
38 where
39 T: Utf8Encoding,
40 {
41 Utf8Path::new(self.as_str())
42 }
43}
44
45impl private::Sealed for Utf8WindowsComponents<'_> {}
46
47impl<'a> Utf8Components<'a> for Utf8WindowsComponents<'a> {
48 type Component = Utf8WindowsComponent<'a>;
49
50 fn as_str(&self) -> &'a str {
51 unsafe { core::str::from_utf8_unchecked(self.inner.as_bytes()) }
54 }
55
56 fn is_absolute(&self) -> bool {
70 self.inner.is_absolute()
71 }
72
73 fn has_root(&self) -> bool {
78 self.inner.has_root()
79 }
80}
81
82impl<'a> Utf8WindowsComponents<'a> {
83 fn peek_front(&self) -> Option<<Self as Utf8Components<'a>>::Component> {
84 self.clone().next()
85 }
86
87 #[inline]
89 pub fn has_prefix(&self) -> bool {
90 self.prefix().is_some()
91 }
92
93 pub fn prefix(&self) -> Option<Utf8WindowsPrefixComponent<'_>> {
95 match self.peek_front() {
96 Some(Utf8WindowsComponent::Prefix(p)) => Some(p),
97 _ => None,
98 }
99 }
100
101 #[inline]
103 pub fn prefix_kind(&self) -> Option<Utf8WindowsPrefix<'_>> {
104 self.prefix().map(|p| p.kind())
105 }
106
107 pub fn has_any_verbatim_prefix(&self) -> bool {
109 matches!(
110 self.prefix_kind(),
111 Some(
112 Utf8WindowsPrefix::Verbatim(_)
113 | Utf8WindowsPrefix::UNC(..)
114 | Utf8WindowsPrefix::Disk(_)
115 )
116 )
117 }
118
119 pub fn has_verbatim_prefix(&self) -> bool {
121 matches!(self.prefix_kind(), Some(Utf8WindowsPrefix::Verbatim(_)))
122 }
123
124 pub fn has_verbatim_unc_prefix(&self) -> bool {
126 matches!(self.prefix_kind(), Some(Utf8WindowsPrefix::VerbatimUNC(..)))
127 }
128
129 pub fn has_verbatim_disk_prefix(&self) -> bool {
131 matches!(self.prefix_kind(), Some(Utf8WindowsPrefix::VerbatimDisk(_)))
132 }
133
134 pub fn has_device_ns_prefix(&self) -> bool {
136 matches!(self.prefix_kind(), Some(Utf8WindowsPrefix::DeviceNS(_)))
137 }
138
139 pub fn has_unc_prefix(&self) -> bool {
141 matches!(self.prefix_kind(), Some(Utf8WindowsPrefix::UNC(..)))
142 }
143
144 pub fn has_disk_prefix(&self) -> bool {
146 matches!(self.prefix_kind(), Some(Utf8WindowsPrefix::Disk(_)))
147 }
148
149 pub fn has_physical_root(&self) -> bool {
154 self.inner.has_physical_root()
155 }
156
157 pub fn has_implicit_root(&self) -> bool {
162 match self.prefix().map(|p| p.kind()) {
163 Some(Utf8WindowsPrefix::Disk(_)) | None => false,
164 Some(_) => true,
165 }
166 }
167}
168
169impl AsRef<[u8]> for Utf8WindowsComponents<'_> {
170 #[inline]
171 fn as_ref(&self) -> &[u8] {
172 self.as_str().as_bytes()
173 }
174}
175
176impl AsRef<str> for Utf8WindowsComponents<'_> {
177 #[inline]
178 fn as_ref(&self) -> &str {
179 self.as_str()
180 }
181}
182
183impl<T> AsRef<Utf8Path<T>> for Utf8WindowsComponents<'_>
184where
185 T: Utf8Encoding,
186{
187 #[inline]
188 fn as_ref(&self) -> &Utf8Path<T> {
189 Utf8Path::new(self.as_str())
190 }
191}
192
193impl fmt::Debug for Utf8WindowsComponents<'_> {
194 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 struct DebugHelper<'a>(Utf8WindowsComponents<'a>);
196
197 impl fmt::Debug for DebugHelper<'_> {
198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199 f.debug_list().entries(self.0.clone()).finish()
200 }
201 }
202
203 f.debug_tuple("Utf8WindowsComponents")
204 .field(&DebugHelper(self.clone()))
205 .finish()
206 }
207}
208
209impl<'a> Iterator for Utf8WindowsComponents<'a> {
210 type Item = <Self as Utf8Components<'a>>::Component;
211
212 fn next(&mut self) -> Option<Self::Item> {
213 self.inner
214 .next()
215 .map(|c| unsafe { Utf8WindowsComponent::from_utf8_unchecked(&c) })
216 }
217}
218
219impl DoubleEndedIterator for Utf8WindowsComponents<'_> {
220 fn next_back(&mut self) -> Option<Self::Item> {
221 self.inner
222 .next_back()
223 .map(|c| unsafe { Utf8WindowsComponent::from_utf8_unchecked(&c) })
224 }
225}
226
227impl iter::FusedIterator for Utf8WindowsComponents<'_> {}
228
229impl cmp::PartialEq for Utf8WindowsComponents<'_> {
230 #[inline]
231 fn eq(&self, other: &Self) -> bool {
232 PartialEq::eq(&self.inner, &other.inner)
233 }
234}
235
236impl cmp::Eq for Utf8WindowsComponents<'_> {}
237
238impl cmp::PartialOrd for Utf8WindowsComponents<'_> {
239 #[inline]
240 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
241 Some(self.cmp(other))
242 }
243}
244
245impl cmp::Ord for Utf8WindowsComponents<'_> {
246 #[inline]
247 fn cmp(&self, other: &Self) -> cmp::Ordering {
248 Ord::cmp(&self.inner, &other.inner)
249 }
250}