orql 0.1.0

A toy SQL parser for a subset of the Oracle dialect.
Documentation
use crate::ast::{BinaryExprOp, CompareKind, UnaryExprOp};

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
pub(super) struct Prec(u8);

pub(super) const MIN_BINDING_POWER: Prec = Prec(0);

pub(super) enum BinaryOp {
    Expr(BinaryExprOp),
    Compare(CompareKind),
    And,
    Or,
}

impl From<CompareKind> for BinaryOp {
    fn from(value: CompareKind) -> Self {
        Self::Compare(value)
    }
}

impl From<BinaryExprOp> for BinaryOp {
    fn from(value: BinaryExprOp) -> Self {
        match value {
            op @ crate::ast::BinaryExprOp::Add
            | op @ crate::ast::BinaryExprOp::Sub
            | op @ crate::ast::BinaryExprOp::Mul
            | op @ crate::ast::BinaryExprOp::Div
            | op @ crate::ast::BinaryExprOp::Concat => Self::Expr(op),
        }
    }
}

pub(super) enum UnaryOp {
    Expr(UnaryExprOp),
    Not,
}

impl From<UnaryExprOp> for UnaryOp {
    fn from(value: UnaryExprOp) -> Self {
        Self::Expr(value)
    }
}

/// Retrieves the precedence for the unary operator.
pub(super) fn unary(op: UnaryOp) -> ((), Prec) {
    match op {
        UnaryOp::Expr(crate::ast::UnaryExprOp::Add | crate::ast::UnaryExprOp::Sub) => {
            ((), Prec(18))
        }
        UnaryOp::Not => ((), Prec(8)),
    }
}

/// Retrieves the precedence for the binary operator.
pub(super) fn binary(op: BinaryOp) -> (Prec, Prec) {
    match op {
        BinaryOp::Expr(op) => match op {
            BinaryExprOp::Mul | BinaryExprOp::Div => (Prec(15), Prec(16)),
            BinaryExprOp::Add | BinaryExprOp::Sub | BinaryExprOp::Concat => (Prec(13), Prec(14)),
        },
        BinaryOp::Compare(op) => match op {
            CompareKind::Eq
            | CompareKind::NotEq(_)
            | CompareKind::Lt
            | CompareKind::LtEq
            | CompareKind::Gt
            | CompareKind::GtEq => (Prec(11), Prec(12)),
        },
        // XXX IS NULL / LIKE / BETWEEN / IN / EXISTS => (Prec(9), Prec(10))
        BinaryOp::And => (Prec(5), Prec(6)),
        BinaryOp::Or => (Prec(3), Prec(4)),
    }
}