Expand description
Reference resolution (P1.3, issue #525).
Core is the language: it parses formulas and evaluates them, but it has
no notion of a sheet, a grid, or a named range. Resolver is the seam
through which an embedding application (the workbook crate, a host app, a
test harness) supplies the value a Ref points at.
The evaluator calls Resolver::resolve every time a formula reads a
reference that is not already bound as a local variable (e.g. a LAMBDA
parameter). The resolver owns all workbook semantics:
- a cross-sheet cell ref to a missing sheet ->
ErrorKind::Ref(#REF!), - a bare name that is not a defined name ->
ErrorKind::Name(#NAME?), - an empty cell ->
Value::Empty, - a range ->
Value::Arrayof the cells in reading order.
Core never invents these; it simply forwards the Ref and returns
whatever the resolver decides.
use std::collections::HashMap;
use truecalc_core::{Engine, Ref, Resolver, Value};
/// A resolver backed by a flat map keyed by canonical reference text.
struct MapResolver(HashMap<String, Value>);
impl Resolver for MapResolver {
fn resolve(&mut self, r: &Ref) -> Value {
self.0.get(&r.to_string()).cloned().unwrap_or(Value::Empty)
}
}
let mut cells = HashMap::new();
cells.insert("Data!A1".to_string(), Value::Number(10.0));
cells.insert("Data!B1".to_string(), Value::Number(5.0));
let mut resolver = MapResolver(cells);
let engine = Engine::sheets();
let result = engine.evaluate_with_resolver("=Data!A1+Data!B1", &mut resolver);
assert_eq!(result, Value::Number(15.0));Traits§
Functions§
- extract_
refs - Collect every
Refa formula reads, in left-to-right source order, without re-parsing – the input that lets the workbook build a dependency graph (plan section 3.2).