use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub enum AggFunc { Sum, Avg, Min, Max, Count, } #[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(String, 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, } } }