querydown 0.0.1

An expressive DSL for writing relational database queries that compile to SQL
Documentation
use chumsky::{prelude::*, text::*};

use super::utils::QdParser;
use crate::parsing::values::value;
use crate::{syntax_tree::*, tokens::*};

pub fn expression(condition_set: impl QdParser<ConditionSet>) -> impl QdParser<Expression> {
    recursive(|e| {
        value(condition_set)
            .then(whitespace().ignore_then(composition(e)).repeated())
            .map(|(base, compositions)| Expression { base, compositions })
    })
}

fn composition(expression: impl QdParser<Expression>) -> impl QdParser<Composition> {
    let prefix = choice((
        just(COMPOSITION_PREFIX_SCALAR).to(FunctionDimension::Scalar),
        just(COMPOSITION_PREFIX_AGGREGATE).to(FunctionDimension::Aggregate),
    ));
    let brace_l = whitespace()
        .then(just(COMPOSITION_ARGUMENT_BRACE_L))
        .then(whitespace());
    let brace_r = whitespace()
        .then(just(COMPOSITION_ARGUMENT_BRACE_R))
        .then(whitespace());
    prefix
        .then_ignore(whitespace())
        .then(ident())
        .map(|(dimension, name)| Function { name, dimension })
        .then(expression.delimited_by(brace_l, brace_r).or_not())
        .map(|(function, argument)| Composition { function, argument })
}