qraft-core 0.1.2

Core type system, query model, decoding, and SQL lowering primitives for qraft.
Documentation
//! Join helpers for typed table sources.

use crate::{Boolean, expression::Expression, lower::LowerCtx, query::LowerFromItem};

/// Supported join kinds for emitted SQL.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum JoinKind {
    Left,
    Right,
    Inner,
}

/// A join source paired with its `on` predicate.
pub struct JoinOn<L, R> {
    pub(crate) left: L,
    pub(crate) right: R,
}

/// Lowers a join into the `from` instruction stream.
pub trait LowerJoin {
    /// Appends the join to the lowering context.
    fn lower_join(self, kind: JoinKind, ctx: &mut LowerCtx);
}

impl<L, R> LowerJoin for JoinOn<L, R>
where
    L: LowerFromItem,
    R: Expression,
    R::Type: Boolean,
{
    fn lower_join(self, kind: JoinKind, ctx: &mut LowerCtx) {
        let start = ctx.instrs.len();
        self.left.lower_from_item(ctx);
        let lhs = ctx.instrs.len() - start;
        let rhs = self.right.lower(ctx);
        ctx.instrs.push(crate::RpnInstr::Join { kind, lhs, rhs });
    }
}

/// Adds `.on(...)` to values that can appear on the left side of a join.
pub trait OnJoin: Sized {
    fn on<E>(self, e: E) -> JoinOn<Self, E>
    where
        E: Expression,
        E::Type: Boolean,
    {
        JoinOn {
            left: self,
            right: e,
        }
    }
}

impl<T> OnJoin for T where T: LowerFromItem {}