im_pathtree/path.rs
1// SPDX-FileCopyrightText: The im-pathtree authors
2// SPDX-License-Identifier: MPL-2.0
3
4use std::{ffi::OsStr, fmt, hash::Hash};
5
6/// Borrowed path segment.
7pub trait PathSegment: Eq + Hash + fmt::Debug {
8 /// Check if the segment is empty.
9 #[must_use]
10 fn is_empty(&self) -> bool;
11}
12
13impl PathSegment for str {
14 fn is_empty(&self) -> bool {
15 self.is_empty()
16 }
17}
18
19impl PathSegment for OsStr {
20 fn is_empty(&self) -> bool {
21 self.is_empty()
22 }
23}
24
25/// Decomposition of a path into segments.
26pub trait SegmentedPath<S: PathSegment + ?Sized>: Clone + Eq + Hash + fmt::Debug {
27 /// Iterate over all path segments.
28 ///
29 /// All segments are guaranteed to be non-empty.
30 // TODO: How to avoid boxing the result?
31 #[must_use]
32 fn segments(&self) -> Box<dyn Iterator<Item = &S> + '_>;
33
34 /// Split the path into parent segments and the last child segment.
35 ///
36 /// The returned iterator excludes the last segment that is
37 /// included by [`Self::segments()`].
38 // TODO: How to avoid boxing the result?
39 #[must_use]
40 fn parent_child_segments(&self) -> (Box<dyn Iterator<Item = &S> + '_>, Option<&S>);
41}
42
43/// [`SegmentedPath`] with a root element.
44pub trait RootPath<S: PathSegment + ?Sized>: SegmentedPath<S> {
45 /// Check if the path equals the root path.
46 #[must_use]
47 fn is_root(&self) -> bool;
48}