use std::fmt;
use std::hash::Hash;
pub type PositionInLanguageTerm = TreePosition;
pub type PositionInRewriteProcess = TreePosition;
#[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub struct TreePosition {
absolute_coordinates_from_root: Vec<usize>,
}
impl TreePosition {
pub fn from_absolute_coordinates(absolute_coordinates_from_root: Vec<usize>) -> Self {
Self {
absolute_coordinates_from_root,
}
}
pub fn get_parent_position(&self) -> Option<Self> {
if self.absolute_coordinates_from_root.is_empty() {
None
} else {
let depth = self.get_depth();
let parent = Self::from_absolute_coordinates(
self.absolute_coordinates_from_root[0..(depth - 1)].to_vec(),
);
Some(parent)
}
}
pub fn get_depth(&self) -> usize {
self.absolute_coordinates_from_root.len()
}
pub fn get_root_position() -> Self {
PositionInLanguageTerm {
absolute_coordinates_from_root: vec![],
}
}
pub fn get_position_of_nth_child(&self, n: usize) -> Self {
let mut absolute_coords = self.absolute_coordinates_from_root.clone();
absolute_coords.push(n);
Self::from_absolute_coordinates(absolute_coords)
}
pub fn get_absolute_coordinates_from_root(&self) -> &[usize] {
&self.absolute_coordinates_from_root
}
}
impl fmt::Display for TreePosition {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.absolute_coordinates_from_root.is_empty() {
write!(f, "ε")
} else {
let as_strs: Vec<String> = self
.absolute_coordinates_from_root
.iter()
.map(|x| x.to_string())
.collect();
write!(f, "{:}", as_strs.join("_"))
}
}
}