use super::{Expr, ExprEvaluator};
use crate::err::*;
use crate::eval::*;
#[derive(Debug, Clone)]
pub struct TraversalExpr {
pub object: Index,
pub key: TraversalKey,
}
impl Expr for TraversalExpr {
fn resolve(
&self,
_index: Index,
evaluation: &mut dyn ExprEvaluator,
) -> Result<ValueOrReference, ErrorKind> {
let indexer = match &self.key {
TraversalKey::String(s) => Indexer::String(s.clone()),
TraversalKey::Number(n) => Indexer::Number(*n),
&TraversalKey::Expression(index) => evaluation
.get_value(index)?
.try_into()
.map_err(|_| ErrorKind::ExpressionNotAnIndexer { index })?,
};
let Some(reference) = evaluation.traverse(self.object, &indexer)? else {
return Err(ErrorKind::FieldNotFound {
item: self.object,
name: indexer.to_string(),
});
};
Ok(reference)
}
fn traverse(
&self,
_evaluation: &dyn ExprEvaluator,
expression: Index,
_name: &Indexer,
) -> Result<Option<ValueOrReference>, ErrorKind> {
Err(ErrorKind::DependenciesNotSatisfied {
indices: vec![expression],
})
}
}