Skip to content

Replace hardcoded function-dispatch match with a FunctionRegistry #77

Description

@garritfra

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    designArchitectural / design workformula-engineFormula tokenizer, parser, evaluatortech-debtTechnical debt — code health, refactor, test coverage

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions