tudor-sql 0.2.0

Does sql stuff to todo.txt files
Documentation
use pest_consume::Parser;

use crate::sql::expression::parser::{ExpressionParser, Result, Rule};
use crate::sql::expression::value::Value;

#[derive(Eq, PartialEq, Debug)]
pub enum ComparisonOperator {
    /// `=`
    Eq,
    /// `<>`  or `!=`
    NotEq,
    /// `>`
    Gt,
    /// `<`
    Lt,
    /// `>=`
    GtEq,
    /// `<=`
    LtEq,
    /// `@>`
    ///
    /// https://www.postgresql.org/docs/9.0/functions-array.html
    Contains,
    /// `<@`
    ///
    /// https://www.postgresql.org/docs/9.0/functions-array.html
    IsContainedBy,
    /// `&&`
    ///
    /// https://www.postgresql.org/docs/9.0/functions-array.html
    Overlap,
}

impl ComparisonOperator {
    pub fn apply(&self, left: &Value, right: &Value) -> Value {
        use ComparisonOperator::*;
        use Value::*;
        match (left, self, right) {
            (Null, _, _) => Null,
            (_, _, Null) => Null,

            (left, Eq, right) => Boolean(left == right),

            _ => unimplemented!("{:#?} {:#?} {:#?}", left, self, right),
        }
    }
    pub fn parse(input: &str) -> Result<ComparisonOperator> {
        let nodes = ExpressionParser::parse(Rule::comparison_operator, input)?;
        let node = nodes.single()?;
        let v = ExpressionParser::comparison_operator(node)?;
        Ok(v)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn parsing_comparison_operator() {
        assert_eq!(
            ComparisonOperator::parse("<>"),
            Ok(ComparisonOperator::NotEq)
        );
        assert_eq!(
            ComparisonOperator::parse("!="),
            Ok(ComparisonOperator::NotEq)
        );
        assert_eq!(ComparisonOperator::parse(">"), Ok(ComparisonOperator::Gt));
        assert_eq!(ComparisonOperator::parse("<"), Ok(ComparisonOperator::Lt));
        assert_eq!(
            ComparisonOperator::parse("<="),
            Ok(ComparisonOperator::LtEq)
        );
        assert_eq!(
            ComparisonOperator::parse(">="),
            Ok(ComparisonOperator::GtEq)
        );
        assert_eq!(
            ComparisonOperator::parse("@>"),
            Ok(ComparisonOperator::Contains)
        );
        assert_eq!(
            ComparisonOperator::parse("<@"),
            Ok(ComparisonOperator::IsContainedBy)
        );
        assert_eq!(
            ComparisonOperator::parse("&&"),
            Ok(ComparisonOperator::Overlap)
        );
        assert!(ComparisonOperator::parse("~~>").is_err());
        // NOTE: these still parse as `<` `>`...
        //       but the rest of the grammar should make it not happen, right??
        // assert!(ComparisonOperator::parse("<~~").is_err());
        // assert!(ComparisonOperator::parse("<$>").is_err());
        // assert!(ComparisonOperator::parse(">>=").is_err());
        // assert!(ComparisonOperator::parse("<~>").is_err());
    }
}