automerge/automerge-frontend/src/path.rs
2021-06-09 11:06:54 +01:00

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),
}
}
}