eql_core 0.1.10

EVM Query Language core components
Documentation
use super::{
    chain::Chain,
    entity::Entity,
    entity_id::EntityId,
    types::{Expression, Field, GetExpression},
};
use crate::interpreter::backend::execution_engine::{ExecutionEngine, QueryResult};
use std::error::Error;

#[derive(Debug, thiserror::Error)]
pub enum EQLBuilderError {
    #[error("Fields must be set")]
    MissingFieldsError,
    #[error("Entity must be set")]
    MissingEntityError,
    #[error("EntityId must be set")]
    MissingEntityIdError,
    #[error("Chain must be set")]
    MissingChainError,
    #[error("Builder can only execute one query at a time")]
    SingleQueryError,
}

pub struct EQLBuilder {
    fields: Option<Vec<Field>>,
    entity: Option<Entity>,
    entity_id: Option<EntityId>,
    chain: Option<Chain>,
}

impl EQLBuilder {
    pub fn new() -> Self {
        EQLBuilder {
            fields: None,
            entity: None,
            entity_id: None,
            chain: None,
        }
    }

    pub fn get(&mut self, fields: Vec<Field>) -> &mut Self {
        self.fields = Some(fields);
        self
    }

    pub fn from(&mut self, entity: Entity, entity_id: EntityId) -> &mut Self {
        self.entity = Some(entity);
        self.entity_id = Some(entity_id);
        self
    }

    pub fn on(&mut self, chain: Chain) -> &mut Self {
        self.chain = Some(chain);
        self
    }

    pub async fn run(&self) -> Result<QueryResult, Box<dyn Error>> {
        let expression = self.expression()?;
        let result = ExecutionEngine::new().run(vec![expression]).await?;

        match result.first() {
            Some(result) => Ok(result.clone()),
            None => Err(Box::new(EQLBuilderError::SingleQueryError)),
        }
    }

    fn expression(&self) -> Result<Expression, EQLBuilderError> {
        let fields = self
            .fields
            .clone()
            .ok_or(EQLBuilderError::MissingFieldsError)?;
        let entity = self
            .entity
            .clone()
            .ok_or(EQLBuilderError::MissingEntityError)?;
        let entity_id = self
            .entity_id
            .clone()
            .ok_or(EQLBuilderError::MissingEntityIdError)?;
        let chain = self
            .chain
            .clone()
            .ok_or(EQLBuilderError::MissingChainError)?;

        Ok(Expression::Get(GetExpression {
            fields,
            entity,
            entity_id,
            chain,
            query: "".to_string(),
        }))
    }
}