use crate::expression::ast::expression::ExpressionTrait;
use crate::proto::gen::expression::{Expression, LogicalExpression, LogicalOperator};
use std::fmt::{Display, Formatter};
impl Display for LogicalOperator {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
LogicalOperator::Or => write!(f, "||"),
LogicalOperator::And => write!(f, "&&"),
}
}
}
impl LogicalOperator {
pub fn infix_binding_power(&self) -> (f64, f64) {
match self {
LogicalOperator::Or => (6.0, 6.5),
LogicalOperator::And => (7.0, 7.5),
}
}
}
impl LogicalExpression {
pub fn new(lhs: Expression, op: &LogicalOperator, rhs: Expression) -> Self {
Self {
left: Some(Box::new(lhs)),
operator: *op as i32,
right: Some(Box::new(rhs)),
}
}
pub fn to_operator(&self) -> LogicalOperator {
LogicalOperator::from_i32(self.operator).unwrap()
}
pub fn infix_binding_power(&self) -> (f64, f64) {
self.to_operator().infix_binding_power()
}
pub fn left(&self) -> &Expression {
self.left.as_ref().unwrap()
}
pub fn right(&self) -> &Expression {
self.right.as_ref().unwrap()
}
}
impl ExpressionTrait for LogicalExpression {
fn binding_power(&self) -> (f64, f64) {
self.infix_binding_power()
}
}
impl Display for LogicalExpression {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let lhs_bp = self.left().binding_power();
let rhs_bp = self.right().binding_power();
let self_bp = self.binding_power();
let lhs_parens = lhs_bp.1 < self_bp.0;
let rhs_parens = rhs_bp.0 < self_bp.1;
if lhs_parens {
write!(f, "({})", self.left())?;
} else {
write!(f, "{}", self.left())?;
}
write!(f, " {} ", self.to_operator())?;
if rhs_parens {
write!(f, "({})", self.right())
} else {
write!(f, "{}", self.right())
}
}
}