use std::sync::Arc;
use crate::tree::ast::expression::{
BinaryOperator, Expression, UnaryPostfixOperator, UnaryPrefixOperator,
};
use crate::tree::ast::node::Span;
use crate::tree::ast::ops::{BinaryOp, UnaryPostfixOp, UnaryPrefixOp};
use crate::tree::builder::null;
use super::{ExpressionBuilder, IntoExpressionBuilder};
#[derive(Debug)]
pub struct BinaryOperatorBuilder {
operator: BinaryOp,
left: Box<dyn ExpressionBuilder>,
right: Box<dyn ExpressionBuilder>,
}
impl BinaryOperatorBuilder {
pub fn new(
operator: impl Into<BinaryOp>,
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> Self {
Self {
operator: operator.into(),
left: left.into_expression_builder(),
right: right.into_expression_builder(),
}
}
}
impl ExpressionBuilder for BinaryOperatorBuilder {
fn build(&self) -> Expression {
Expression {
span: Span::NONE,
kind: BinaryOperator {
operator: self.operator.clone(),
left: Arc::new(self.left.build()),
right: Arc::new(self.right.build()),
}
.into(),
}
}
}
impl IntoExpressionBuilder for BinaryOperatorBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
#[derive(Debug)]
pub struct UnaryPrefixOperatorBuilder {
operator: UnaryPrefixOp,
operand: Box<dyn ExpressionBuilder>,
}
impl UnaryPrefixOperatorBuilder {
pub fn new(operator: impl Into<UnaryPrefixOp>, operand: impl IntoExpressionBuilder) -> Self {
Self {
operator: operator.into(),
operand: operand.into_expression_builder(),
}
}
}
impl ExpressionBuilder for UnaryPrefixOperatorBuilder {
fn build(&self) -> Expression {
Expression {
span: Span::NONE,
kind: UnaryPrefixOperator {
operator: self.operator.clone(),
operand: Arc::new(self.operand.build()),
}
.into(),
}
}
}
impl IntoExpressionBuilder for UnaryPrefixOperatorBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
#[derive(Debug)]
pub struct UnaryPostfixOperatorBuilder {
operator: UnaryPostfixOp,
operand: Box<dyn ExpressionBuilder>,
}
impl UnaryPostfixOperatorBuilder {
pub fn new(operator: impl Into<UnaryPostfixOp>, operand: impl IntoExpressionBuilder) -> Self {
Self {
operator: operator.into(),
operand: operand.into_expression_builder(),
}
}
}
impl ExpressionBuilder for UnaryPostfixOperatorBuilder {
fn build(&self) -> Expression {
Expression {
span: Span::NONE,
kind: UnaryPostfixOperator {
operator: self.operator.clone(),
operand: Arc::new(self.operand.build()),
}
.into(),
}
}
}
impl IntoExpressionBuilder for UnaryPostfixOperatorBuilder {
fn into_expression_builder(self) -> Box<dyn ExpressionBuilder> {
Box::new(self)
}
}
pub fn add(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Add, left, right)
}
pub fn subtract(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Subtract, left, right)
}
pub fn multiply(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Multiply, left, right)
}
pub fn divide(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Divide, left, right)
}
pub fn modulo(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Modulo, left, right)
}
pub fn eq(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Equal, left, right)
}
pub fn ne(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::NotEqual, left, right)
}
pub fn lt(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::LessThan, left, right)
}
pub fn lte(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::LessThanOrEqual, left, right)
}
pub fn gt(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::GreaterThan, left, right)
}
pub fn gte(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::GreaterThanOrEqual, left, right)
}
pub fn and(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::And, left, right)
}
pub fn or(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Or, left, right)
}
pub fn negate(operand: impl IntoExpressionBuilder) -> UnaryPrefixOperatorBuilder {
UnaryPrefixOperatorBuilder::new(UnaryPrefixOp::Minus, operand)
}
pub fn not(operand: impl IntoExpressionBuilder) -> UnaryPrefixOperatorBuilder {
UnaryPrefixOperatorBuilder::new(UnaryPrefixOp::Not, operand)
}
pub fn is_null(operand: impl IntoExpressionBuilder) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::Is, operand, null())
}
pub fn is_not_null(operand: impl IntoExpressionBuilder) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::IsNot, operand, null())
}
pub fn in_(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::In, left, right)
}
pub fn not_in(
left: impl IntoExpressionBuilder,
right: impl IntoExpressionBuilder,
) -> BinaryOperatorBuilder {
BinaryOperatorBuilder::new(BinaryOp::NotIn, left, right)
}