logisheets_controller/calc_engine/calculator/funcs/
countblank.rs1use 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}