docs: update repo-map for _Measure, CellValue::Error, fixed-point eval

Reflect _Measure virtual category, VirtualMeasure kind, CellValue::Error
variant, recompute_formulas fixed-point cache, and add_formula auto-adding
target items.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Edward Langley
2026-04-09 02:43:15 -07:00
parent afbcf7b3ff
commit 326e245c48

View File

@ -93,10 +93,11 @@ pub struct Model {
// set_cell(&mut self, key: CellKey, value: CellValue) // set_cell(&mut self, key: CellKey, value: CellValue)
// evaluate(&self, key: &CellKey) -> Option<CellValue> [formulas + raw data] // evaluate(&self, key: &CellKey) -> Option<CellValue> [formulas + raw data]
// evaluate_aggregated(&self, key, none_cats) -> Option<CellValue> [sums over hidden dims] // evaluate_aggregated(&self, key, none_cats) -> Option<CellValue> [sums over hidden dims]
// add_formula(&mut self, formula: Formula) [replaces same target+category] // recompute_formulas(&mut self, none_cats) [fixed-point formula cache]
// add_formula(&mut self, formula: Formula) [replaces same target+category, adds item]
// remove_formula(&mut self, target, category) // remove_formula(&mut self, target, category)
// category_names(&self) -> Vec<&str> [includes virtual] // category_names(&self) -> Vec<&str> [includes virtual]
// regular_category_names(&self) -> Vec<&str> [excludes _Index, _Dim] // regular_category_names(&self) -> Vec<&str> [excludes _Index, _Dim, _Measure]
const MAX_CATEGORIES: usize = 12; // virtual categories don't count const MAX_CATEGORIES: usize = 12; // virtual categories don't count
``` ```
@ -114,8 +115,10 @@ pub struct CellKey(pub Vec<(String, String)>); // always sorted by category nam
pub enum CellValue { pub enum CellValue {
Number(f64), Number(f64),
Text(String), Text(String),
Error(String), // formula evaluation error (circular ref, div/0, etc.)
} }
// CellValue::as_f64() -> Option<f64> // CellValue::as_f64() -> Option<f64>
// CellValue::is_error() -> bool
pub struct DataStore { pub struct DataStore {
cells: HashMap<InternedKey, CellValue>, cells: HashMap<InternedKey, CellValue>,
@ -141,7 +144,7 @@ pub struct Category {
// Category::add_item(&mut self, name) -> ItemId [deduplicates by name] // Category::add_item(&mut self, name) -> ItemId [deduplicates by name]
// Category::ordered_item_names(&self) -> Vec<&str> [respects group order] // Category::ordered_item_names(&self) -> Vec<&str> [respects group order]
pub enum CategoryKind { Regular, VirtualIndex, VirtualDim, Label } pub enum CategoryKind { Regular, VirtualIndex, VirtualDim, VirtualMeasure, Label }
``` ```
### Formula System ### Formula System
@ -480,8 +483,9 @@ examples).
1. **Commands never mutate.** They receive `&CmdContext` (read-only) and return `Vec<Box<dyn Effect>>`. 1. **Commands never mutate.** They receive `&CmdContext` (read-only) and return `Vec<Box<dyn Effect>>`.
2. **CellKey is always sorted.** Use `CellKey::new()` — never construct the inner Vec directly. 2. **CellKey is always sorted.** Use `CellKey::new()` — never construct the inner Vec directly.
3. **`category_mut()` for adding items.** `Model` has no `add_item` method; get the category first: `m.category_mut("Region").unwrap().add_item("East")`. 3. **`category_mut()` for adding items.** `Model` has no `add_item` method; get the category first: `m.category_mut("Region").unwrap().add_item("East")`.
4. **Virtual categories** `_Index` and `_Dim` always exist. `is_empty_model()` checks whether any *non-virtual* categories exist. 4. **Virtual categories** `_Index`, `_Dim`, and `_Measure` always exist. `is_empty_model()` checks whether any *non-virtual* categories exist. `_Measure` holds numeric data fields and formula targets; `add_formula` auto-adds the target item.
5. **Display rounding is view-only.** `format_f64` (half-away-from-zero) is only called in rendering. Formula eval uses full f64. 5. **Display rounding is view-only.** `format_f64` (half-away-from-zero) is only called in rendering. Formula eval uses full f64.
5b. **Formula evaluation is fixed-point.** `recompute_formulas(none_cats)` iterates formula evaluation until values stabilize, using a cache. `evaluate_aggregated` checks the cache for formula results. Circular refs produce `CellValue::Error("circular")`.
6. **Keybindings are per-mode.** `ModeKey::from_app_mode()` resolves the current mode, then the corresponding `Keymap` is looked up. Normal + `search_mode=true` maps to `SearchMode`. 6. **Keybindings are per-mode.** `ModeKey::from_app_mode()` resolves the current mode, then the corresponding `Keymap` is looked up. Normal + `search_mode=true` maps to `SearchMode`.
7. **`effect_cmd!` macro** generates a command struct that just produces effects. Use for simple commands without complex logic. 7. **`effect_cmd!` macro** generates a command struct that just produces effects. Use for simple commands without complex logic.
8. **`.improv` format is markdown-like**, not JSON. See `persistence/mod.rs`. JSON is legacy only. 8. **`.improv` format is markdown-like**, not JSON. See `persistence/mod.rs`. JSON is legacy only.