radiate-expr 1.2.22

A Rust library for genetic algorithms and artificial evolution.
Documentation
use crate::{AnyValue, Expr, ExprProjection, ExprQuery, ExprResult, Field};
use radiate_error::radiate_bail;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Debug, PartialEq)]
pub enum PathSegment {
    Key(AnyValue<'static>),
    Index(usize),
    StructField(Field),
}

#[derive(Clone, Debug, PartialEq, Default)]
pub struct PathBuilder {
    path: Vec<PathSegment>,
}

impl PathBuilder {
    pub fn key(mut self, key: impl Into<AnyValue<'static>>) -> Self {
        self.path.push(PathSegment::Key(key.into()));
        self
    }

    pub fn index(mut self, index: usize) -> Self {
        self.path.push(PathSegment::Index(index));
        self
    }

    pub fn field(mut self, field: Field) -> Self {
        self.path.push(PathSegment::StructField(field));
        self
    }
}

impl Into<Expr> for PathBuilder {
    fn into(self) -> Expr {
        Expr::Selector(SelectExpr::Path(self.path))
    }
}

#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum SelectExpr {
    Field(AnyValue<'static>, Field),
    Nth(usize),
    Path(Vec<PathSegment>),
    Element,
}

impl<T> ExprQuery<T> for SelectExpr
where
    T: ExprProjection,
{
    fn dispatch<'a>(&'a mut self, input: &T) -> ExprResult<'a> {
        if let Some(result) = input.project(self) {
            Ok(result)
        } else {
            radiate_bail!(Expr: "Failed to project value using selector {:?}", self)
        }
    }
}