Skip to main content

radiate_expr/expression/
select.rs

1use crate::{AnyValue, Expr, ExprProjection, ExprQuery, ExprResult, Field};
2use radiate_error::radiate_bail;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7#[derive(Clone, Debug, PartialEq)]
8pub enum PathSegment {
9    Key(AnyValue<'static>),
10    Index(usize),
11    StructField(Field),
12}
13
14#[derive(Clone, Debug, PartialEq, Default)]
15pub struct PathBuilder {
16    path: Vec<PathSegment>,
17}
18
19impl PathBuilder {
20    pub fn key(mut self, key: impl Into<AnyValue<'static>>) -> Self {
21        self.path.push(PathSegment::Key(key.into()));
22        self
23    }
24
25    pub fn index(mut self, index: usize) -> Self {
26        self.path.push(PathSegment::Index(index));
27        self
28    }
29
30    pub fn field(mut self, field: Field) -> Self {
31        self.path.push(PathSegment::StructField(field));
32        self
33    }
34}
35
36impl Into<Expr> for PathBuilder {
37    fn into(self) -> Expr {
38        Expr::Selector(SelectExpr::Path(self.path))
39    }
40}
41
42#[derive(Clone, Debug, PartialEq)]
43#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
44pub enum SelectExpr {
45    Field(AnyValue<'static>, Field),
46    Nth(usize),
47    Path(Vec<PathSegment>),
48    Element,
49}
50
51impl<T> ExprQuery<T> for SelectExpr
52where
53    T: ExprProjection,
54{
55    fn dispatch<'a>(&'a mut self, input: &T) -> ExprResult<'a> {
56        if let Some(result) = input.project(self) {
57            Ok(result)
58        } else {
59            radiate_bail!(Expr: "Failed to project value using selector {:?}", self)
60        }
61    }
62}