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:
@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user