From f02d905aac40eb08da570be6b67e9f634697491b Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Tue, 14 Apr 2026 01:49:16 -0700 Subject: [PATCH] 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) --- Cargo.lock | 9 +++++++++ Cargo.toml | 4 ++++ context/repo-map.md | 16 +++++++++------- crates/improvise-formula/Cargo.toml | 11 +++++++++++ .../improvise-formula/src}/ast.rs | 0 .../improvise-formula/src/lib.rs | 0 .../improvise-formula/src}/parser.rs | 2 +- src/lib.rs | 2 +- 8 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 crates/improvise-formula/Cargo.toml rename {src/formula => crates/improvise-formula/src}/ast.rs (100%) rename src/formula/mod.rs => crates/improvise-formula/src/lib.rs (100%) rename {src/formula => crates/improvise-formula/src}/parser.rs (99%) diff --git a/Cargo.lock b/Cargo.lock index a219f13..a3d10bf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -737,6 +737,7 @@ dependencies = [ "dirs", "enum_dispatch", "flate2", + "improvise-formula", "indexmap", "pest", "pest_derive", @@ -750,6 +751,14 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "improvise-formula" +version = "0.1.0-rc2" +dependencies = [ + "anyhow", + "serde", +] + [[package]] name = "indexmap" version = "2.14.0" diff --git a/Cargo.toml b/Cargo.toml index 2d15405..658acfa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,6 @@ +[workspace] +members = [".", "crates/improvise-formula"] + [package] name = "improvise" version = "0.1.0-rc2" @@ -15,6 +18,7 @@ name = "improvise" path = "src/main.rs" [dependencies] +improvise-formula = { path = "crates/improvise-formula" } ratatui = "0.30" crossterm = "0.29" serde = { version = "1", features = ["derive"] } diff --git a/context/repo-map.md b/context/repo-map.md index f7bfe98..98befb9 100644 --- a/context/repo-map.md +++ b/context/repo-map.md @@ -1,8 +1,10 @@ # Repository Map (LLM Reference) Terminal pivot-table modeling app. Rust, Ratatui TUI, command/effect architecture. -Crate `improvise` v0.1.0-rc2, Apache-2.0, edition 2024. +Cargo workspace, Apache-2.0, edition 2024. Root package `improvise` v0.1.0-rc2. Library + binary crate: `src/lib.rs` exports public modules, `src/main.rs` is the CLI entry. +Sub-crates live under `crates/`: +- `crates/improvise-formula/` — formula parser, AST (`Expr`, `BinOp`, `AggFunc`, `Formula`, `Filter`), `parse_formula`. Re-exported as `crate::formula` from the main crate via `pub use improvise_formula as formula;`. --- @@ -153,7 +155,7 @@ pub enum CategoryKind { Regular, VirtualIndex, VirtualDim, VirtualMeasure, Label ### Formula System ```rust -// src/formula/ast.rs +// crates/improvise-formula/src/ast.rs pub enum Expr { Number(f64), Ref(String), // reference to an item name @@ -172,7 +174,7 @@ pub struct Formula { pub filter: Option, // WHERE clause } -// src/formula/parser.rs +// crates/improvise-formula/src/parser.rs pub fn parse_formula(raw: &str, target_category: &str) -> Result ``` @@ -383,11 +385,11 @@ Lines / tests / path — grouped by layer. 6 / 0t model/mod.rs ``` -### Formula layer +### Formula layer (sub-crate `improvise-formula` under `crates/`) ``` - 461 / 29t formula/parser.rs Recursive descent parser → Formula AST - 77 / 0t formula/ast.rs Expr, BinOp, AggFunc, Formula, Filter (data only) - 5 / 0t formula/mod.rs + 776 / 35t crates/improvise-formula/src/parser.rs Recursive descent parser → Formula AST + 77 / 0t crates/improvise-formula/src/ast.rs Expr, BinOp, AggFunc, Formula, Filter (data only) + 5 / 0t crates/improvise-formula/src/lib.rs ``` ### View layer diff --git a/crates/improvise-formula/Cargo.toml b/crates/improvise-formula/Cargo.toml new file mode 100644 index 0000000..338e0e6 --- /dev/null +++ b/crates/improvise-formula/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "improvise-formula" +version = "0.1.0-rc2" +edition = "2024" +description = "Formula parser and AST for improvise" +license = "Apache-2.0" +repository = "https://github.com/fiddlerwoaroof/improvise" + +[dependencies] +anyhow = "1" +serde = { version = "1", features = ["derive"] } diff --git a/src/formula/ast.rs b/crates/improvise-formula/src/ast.rs similarity index 100% rename from src/formula/ast.rs rename to crates/improvise-formula/src/ast.rs diff --git a/src/formula/mod.rs b/crates/improvise-formula/src/lib.rs similarity index 100% rename from src/formula/mod.rs rename to crates/improvise-formula/src/lib.rs diff --git a/src/formula/parser.rs b/crates/improvise-formula/src/parser.rs similarity index 99% rename from src/formula/parser.rs rename to crates/improvise-formula/src/parser.rs index 9c250f6..01df646 100644 --- a/src/formula/parser.rs +++ b/crates/improvise-formula/src/parser.rs @@ -460,7 +460,7 @@ fn parse_comparison(tokens: &[Token], pos: &mut usize) -> Result { #[cfg(test)] mod tests { use super::parse_formula; - use crate::formula::{AggFunc, BinOp, Expr}; + use crate::{AggFunc, BinOp, Expr}; #[test] fn parse_simple_subtraction() { diff --git a/src/lib.rs b/src/lib.rs index 0eb8480..a96fce3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ pub mod command; pub mod draw; pub mod format; -pub mod formula; +pub use improvise_formula as formula; pub mod import; pub mod model; pub mod persistence;