use std::ops::{Add, Mul};
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct TreePath(Vec<usize>);
impl TreePath {
pub fn new() -> Self {
Self::default()
}
pub fn push(&mut self, index: usize) {
self.0.push(index);
}
pub fn pop(&mut self) -> Option<usize> {
self.0.pop()
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn as_slice(&self) -> &[usize] {
&self.0
}
pub fn iter(&self) -> std::slice::Iter<'_, usize> {
self.0.iter()
}
pub fn into_vec(self) -> Vec<usize> {
self.0
}
}
impl From<Vec<usize>> for TreePath {
fn from(path: Vec<usize>) -> Self {
Self(path)
}
}
impl AsRef<[usize]> for TreePath {
fn as_ref(&self) -> &[usize] {
self.as_slice()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct PathStep {
pub i: usize,
pub a: usize,
}
impl PathStep {
pub fn new(i: usize, a: usize) -> Self {
Self { i, a }
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
pub struct GrammarPath {
steps: Vec<PathStep>,
}
impl Ord for GrammarPath {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
match self.steps.len().cmp(&other.steps.len()) {
std::cmp::Ordering::Equal => self.steps.cmp(&other.steps),
ord => ord,
}
}
}
impl PartialOrd for GrammarPath {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl GrammarPath {
pub fn new() -> Self {
Self { steps: Vec::new() }
}
pub fn push(&mut self, step: PathStep) {
self.steps.push(step);
}
pub fn pop(&mut self) -> Option<PathStep> {
self.steps.pop()
}
pub fn is_empty(&self) -> bool {
self.steps.is_empty()
}
pub fn len(&self) -> usize {
self.steps.len()
}
pub fn steps(&self) -> &[PathStep] {
&self.steps
}
pub fn iter(&self) -> std::slice::Iter<'_, PathStep> {
self.steps.iter()
}
pub fn forward(&self) -> Option<(PathStep, Self)> {
let first = self.steps.first().cloned()?;
let rest = self.steps[1..].to_vec();
Some((first, Self { steps: rest }))
}
pub fn alts(&self) -> Vec<usize> {
self.steps.iter().map(|step| step.a).collect()
}
pub fn indices(&self) -> Vec<usize> {
self.steps.iter().map(|step| step.i).collect()
}
pub fn idxs(&self) -> Vec<usize> {
self.indices()
}
}
impl Add for GrammarPath {
type Output = Self;
fn add(mut self, rhs: Self) -> Self {
self.steps.extend(rhs.steps);
self
}
}
impl Mul<PathStep> for GrammarPath {
type Output = Self;
fn mul(mut self, rhs: PathStep) -> Self {
self.steps.push(rhs);
self
}
}
impl From<Vec<PathStep>> for GrammarPath {
fn from(steps: Vec<PathStep>) -> Self {
Self { steps }
}
}