use super::expr::Expr;
#[derive(Debug, Clone, PartialEq)]
pub struct Formula {
pub(crate) expr: Expr,
}
impl Formula {
pub(crate) fn new(expr: Expr) -> Self {
Formula { expr }
}
#[must_use]
pub fn coalesce(self, other: Self) -> Self {
Formula::new(self.expr.coalesce(other.expr))
}
#[must_use]
pub fn min(self, other: Self) -> Self {
Formula::new(self.expr.min(other.expr))
}
#[must_use]
pub fn max(self, other: Self) -> Self {
Formula::new(self.expr.max(other.expr))
}
}
impl From<Expr> for Formula {
fn from(expr: Expr) -> Self {
Formula { expr }
}
}
impl From<Formula> for Expr {
fn from(formula: Formula) -> Self {
formula.expr
}
}
impl std::ops::Add for Formula {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Formula::new(self.expr + rhs.expr)
}
}
impl std::ops::Sub for Formula {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Formula::new(self.expr - rhs.expr)
}
}
impl std::fmt::Display for Formula {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.expr.fmt(f)
}
}
impl From<Formula> for String {
fn from(formula: Formula) -> Self {
formula.expr.to_string()
}
}
#[cfg(test)]
mod tests {
use super::Formula;
use crate::graph::formulas::expr::Expr;
#[test]
fn test_formula_arith() {
let a = Formula::new(Expr::component(1));
let b = Formula::new(Expr::component(2));
assert_eq!((a.clone() + b.clone()).to_string(), "#1 + #2");
assert_eq!((a - b).to_string(), "#1 - #2");
}
#[test]
fn test_formula_combinators() {
let a = Formula::new(Expr::component(1));
let b = Formula::new(Expr::component(2));
assert_eq!(
a.clone().coalesce(b.clone()).to_string(),
"COALESCE(#1, #2)"
);
assert_eq!(a.clone().min(b.clone()).to_string(), "MIN(#1, #2)");
assert_eq!(a.max(b).to_string(), "MAX(#1, #2)");
}
}