Problem
crates/cell-sheet-core/src/formula/eval.rs:115–145 dispatches built-in functions through a hand-written match:
match upper.as_str() {
"SUM" => functions::fn_sum(&values),
"AVERAGE" => functions::fn_average(&values),
"COUNT" => functions::fn_count(&values),
"MIN" => functions::fn_min(&values),
"MAX" => functions::fn_max(&values),
_ => CellValue::Error(CellError::Name),
}
IF is special-cased earlier (lines 118–121) because it needs lazy/short-circuit evaluation of its branches. Adding a new function requires editing both this match and functions.rs, and there's no clean place to add lazy-eval functions (AND, OR, IFERROR).
Proposed fix
Introduce a FunctionRegistry that supports both eager and lazy variants:
enum BuiltIn {
Eager(fn(&[CellValue]) -> CellValue),
Lazy(fn(&[Expr], &Sheet) -> CellValue),
}
Register all built-ins by name. eval.rs looks up and dispatches; functions.rs becomes the single place to add new functions.
Unblocks the next batch (AND, OR, CONCAT, LEN, ROUND, IFERROR) without touching the dispatcher.
Priority
MEDIUM — refactor only, but high leverage for upcoming function work.
Problem
crates/cell-sheet-core/src/formula/eval.rs:115–145dispatches built-in functions through a hand-written match:IFis special-cased earlier (lines 118–121) because it needs lazy/short-circuit evaluation of its branches. Adding a new function requires editing both this match andfunctions.rs, and there's no clean place to add lazy-eval functions (AND,OR,IFERROR).Proposed fix
Introduce a
FunctionRegistrythat supports both eager and lazy variants:Register all built-ins by name.
eval.rslooks up and dispatches;functions.rsbecomes the single place to add new functions.Unblocks the next batch (
AND,OR,CONCAT,LEN,ROUND,IFERROR) without touching the dispatcher.Priority
MEDIUM — refactor only, but high leverage for upcoming function work.