use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub enum AggFunc { Sum, Avg, Min, Max, Count, } /// Arithmetic and comparison operators used in binary expressions. /// Having an enum (rather than a raw String) means the parser must /// produce a valid operator; invalid operators are caught at parse /// time rather than silently returning Empty at eval time. #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum BinOp { Add, Sub, Mul, Div, Pow, Eq, Ne, Lt, Gt, Le, Ge, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Filter { pub category: String, pub item: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum Expr { Number(f64), Ref(String), BinOp(BinOp, Box, Box), UnaryMinus(Box), Agg(AggFunc, Box, Option), If(Box, Box, Box), } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Formula { /// The raw formula text, e.g. "Profit = Revenue - Cost" pub raw: String, /// The item/dimension name this formula computes, e.g. "Profit" pub target: String, /// The category containing the target item pub target_category: String, /// The expression to evaluate pub expr: Expr, /// Optional WHERE filter pub filter: Option, } impl Formula { pub fn new( raw: impl Into, target: impl Into, target_category: impl Into, expr: Expr, filter: Option, ) -> Self { Self { raw: raw.into(), target: target.into(), target_category: target_category.into(), expr, filter, } } }