logisheets_controller 1.16.1

Core spreadsheet engine for LogiSheets: formula evaluation, dependency tracking, and undo/redo.
Documentation
use logisheets_parser::ast;

use crate::calc_engine::connector::Connector;

use super::{CalcValue, CalcVertex, Value};

pub fn calc<C>(args: Vec<CalcVertex>, fetcher: &mut C) -> CalcVertex
where
    C: Connector,
{
    assert_or_return!(args.len() == 1, ast::Error::Unspecified);
    let first = args.into_iter().next().unwrap();
    match &first {
        CalcVertex::Reference(_) => {
            let values = fetcher.get_calc_value(first);
            let num = match values {
                CalcValue::Scalar(s) => {
                    if is_blank(s) {
                        1.
                    } else {
                        0.
                    }
                }
                CalcValue::Range(r) => r
                    .into_iter()
                    .fold(0., |prev, v| if is_blank(v) { prev + 1. } else { prev }),
                CalcValue::Cube(c) => c
                    .into_iter()
                    .fold(0., |prev, v| if is_blank(v) { prev + 1. } else { prev }),
                CalcValue::Union(_) => unreachable!(),
            };
            CalcVertex::from_number(num)
        }
        _ => CalcVertex::from_error(ast::Error::Unspecified),
    }
}

fn is_blank(v: Value) -> bool {
    match v {
        Value::Blank => true,
        Value::Text(s) => {
            if s.is_empty() {
                true
            } else {
                false
            }
        }
        _ => false,
    }
}