use super::Expression;
use crate::Identifier;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Traversal {
pub expr: Expression,
pub operators: Vec<TraversalOperator>,
}
impl Traversal {
pub fn new<E, I>(expr: E, operators: I) -> Self
where
E: Into<Expression>,
I: IntoIterator,
I::Item: Into<TraversalOperator>,
{
Traversal {
expr: expr.into(),
operators: operators.into_iter().map(Into::into).collect(),
}
}
pub fn builder<T>(expr: T) -> TraversalBuilder
where
T: Into<Expression>,
{
TraversalBuilder {
expr: expr.into(),
operators: Vec::new(),
}
}
}
#[derive(Debug)]
pub struct TraversalBuilder {
expr: Expression,
operators: Vec<TraversalOperator>,
}
impl TraversalBuilder {
pub fn attr<T>(mut self, ident: T) -> Self
where
T: Into<Identifier>,
{
self.operators
.push(TraversalOperator::GetAttr(ident.into()));
self
}
pub fn attr_splat(mut self) -> Self {
self.operators.push(TraversalOperator::AttrSplat);
self
}
pub fn full_splat(mut self) -> Self {
self.operators.push(TraversalOperator::FullSplat);
self
}
pub fn index<T>(mut self, expr: T) -> Self
where
T: Into<Expression>,
{
self.operators.push(TraversalOperator::Index(expr.into()));
self
}
pub fn build(self) -> Traversal {
Traversal {
expr: self.expr,
operators: self.operators,
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)]
pub enum TraversalOperator {
AttrSplat,
FullSplat,
GetAttr(Identifier),
Index(Expression),
LegacyIndex(u64),
}
impl<T> From<T> for TraversalOperator
where
T: Into<Identifier>,
{
fn from(value: T) -> TraversalOperator {
TraversalOperator::GetAttr(value.into())
}
}
impl From<Expression> for TraversalOperator {
fn from(value: Expression) -> TraversalOperator {
TraversalOperator::Index(value)
}
}
impl From<u64> for TraversalOperator {
fn from(value: u64) -> TraversalOperator {
TraversalOperator::LegacyIndex(value)
}
}