logisheets_controller/calc_engine/calculator/funcs/
countblank.rs

1use logisheets_parser::ast;
2
3use crate::calc_engine::connector::Connector;
4
5use super::{CalcValue, CalcVertex, Value};
6
7pub fn calc<C>(args: Vec<CalcVertex>, fetcher: &mut C) -> CalcVertex
8where
9    C: Connector,
10{
11    assert_or_return!(args.len() == 1, ast::Error::Unspecified);
12    let first = args.into_iter().next().unwrap();
13    match &first {
14        CalcVertex::Reference(_) => {
15            let values = fetcher.get_calc_value(first);
16            let num = match values {
17                CalcValue::Scalar(s) => {
18                    if is_blank(s) {
19                        1.
20                    } else {
21                        0.
22                    }
23                }
24                CalcValue::Range(r) => {
25                    r.into_iter()
26                        .fold(0., |prev, v| if is_blank(v) { prev + 1. } else { prev })
27                }
28                CalcValue::Cube(c) => {
29                    c.into_iter()
30                        .fold(0., |prev, v| if is_blank(v) { prev + 1. } else { prev })
31                }
32                CalcValue::Union(_) => unreachable!(),
33            };
34            CalcVertex::from_number(num)
35        }
36        _ => CalcVertex::from_error(ast::Error::Unspecified),
37    }
38}
39
40fn is_blank(v: Value) -> bool {
41    match v {
42        Value::Blank => true,
43        Value::Text(s) => {
44            if s.is_empty() {
45                true
46            } else {
47                false
48            }
49        }
50        _ => false,
51    }
52}