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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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