58 lines
1.3 KiB
Rust
58 lines
1.3 KiB
Rust
use std::fmt;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub(crate) enum PathElement {
|
|
Key(String),
|
|
Index(u32),
|
|
}
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub struct Path(Vec<PathElement>);
|
|
|
|
impl Path {
|
|
pub fn root() -> Path {
|
|
Path(Vec::new())
|
|
}
|
|
|
|
pub fn index(mut self, index: u32) -> Self {
|
|
self.0.push(PathElement::Index(index));
|
|
self
|
|
}
|
|
|
|
pub fn key<S: Into<String>>(mut self, key: S) -> Path {
|
|
self.0.push(PathElement::Key(key.into()));
|
|
self
|
|
}
|
|
|
|
pub fn parent(&self) -> Self {
|
|
if self.0.is_empty() {
|
|
Path(Vec::new())
|
|
} else {
|
|
let mut new_path = self.0.clone();
|
|
new_path.pop();
|
|
Path(new_path)
|
|
}
|
|
}
|
|
|
|
/// Get the final component of the path, if any
|
|
pub(crate) fn name(&self) -> Option<&PathElement> {
|
|
self.0.last()
|
|
}
|
|
|
|
pub(crate) fn elements(self) -> Vec<PathElement> {
|
|
self.0
|
|
}
|
|
|
|
pub(crate) fn is_root(&self) -> bool {
|
|
self.0.is_empty()
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for PathElement {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match self {
|
|
PathElement::Key(k) => write!(f, "{}", k),
|
|
PathElement::Index(i) => write!(f, "{}", i),
|
|
}
|
|
}
|
|
}
|