refactor(formula): extract formula parser into separate crate
Extract the formula AST and parser into a dedicated `improvise-formula` crate and convert the project into a Cargo workspace. The root crate now re-exports `improvise-formula` as `crate::formula` to maintain backward compatibility for internal callers. The repository map is updated to reflect the new crate structure. Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
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<Expr>, Box<Expr>),
|
||||
UnaryMinus(Box<Expr>),
|
||||
Agg(AggFunc, Box<Expr>, Option<Filter>),
|
||||
If(Box<Expr>, Box<Expr>, Box<Expr>),
|
||||
}
|
||||
|
||||
#[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<Filter>,
|
||||
}
|
||||
|
||||
impl Formula {
|
||||
pub fn new(
|
||||
raw: impl Into<String>,
|
||||
target: impl Into<String>,
|
||||
target_category: impl Into<String>,
|
||||
expr: Expr,
|
||||
filter: Option<Filter>,
|
||||
) -> Self {
|
||||
Self {
|
||||
raw: raw.into(),
|
||||
target: target.into(),
|
||||
target_category: target_category.into(),
|
||||
expr,
|
||||
filter,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user