logisheets_controller/calc_engine/calculator/funcs/
mode.rs1use crate::calc_engine::{
2 calculator::calc_vertex::{CalcValue, CalcVertex, Value},
3 connector::Connector,
4};
5use logisheets_parser::ast;
6use std::collections::BTreeMap;
7
8pub fn calc<C>(args: Vec<CalcVertex>, fetcher: &mut C) -> CalcVertex
9where
10 C: Connector,
11{
12 let mut bmap = BTreeMap::new();
13 for arg in args.into_iter() {
14 let value = fetcher.get_calc_value(arg);
15 if let Err(e) = count_an_arg(value, &mut bmap) {
16 return CalcVertex::from_error(e);
17 }
18 }
19 let mut max = 0;
20 let mut position = 0;
21 let mut result = String::from("");
22
23 bmap.into_iter().for_each(|(k, (cnt, p))| {
24 if cnt > max {
25 result = k;
26 max = cnt;
27 position = p;
28 } else if cnt == max && position > p {
29 position = p;
30 result = k;
31 }
32 });
33
34 let num = result.parse::<f64>().unwrap();
35 CalcVertex::from_number(num)
36}
37
38fn count_an_arg(
39 value: CalcValue,
40 bmap: &mut BTreeMap<String, (u32, usize)>,
41) -> Result<(), ast::Error> {
42 match value {
43 CalcValue::Scalar(s) => match s {
44 Value::Number(num) => {
45 let s = num.to_string();
46 let l = bmap.len();
47 let insert = bmap.entry(s).or_insert((0, l));
48 insert.0 += 1;
49 Ok(())
50 }
51 Value::Error(e) => Err(e),
52 _ => Err(ast::Error::Value),
53 },
54 CalcValue::Range(r) => {
55 r.into_iter().for_each(|v| match v {
56 Value::Number(num) => {
57 let s = num.to_string();
58 let l = bmap.len();
59 let insert = bmap.entry(s).or_insert((0, l));
60 insert.0 += 1;
61 }
62 _ => {}
63 });
64 Ok(())
65 }
66 CalcValue::Cube(c) => {
67 c.into_iter().for_each(|v| match v {
68 Value::Number(num) => {
69 let s = num.to_string();
70 let l = bmap.len();
71 let insert = bmap.entry(s).or_insert((0, l));
72 insert.0 += 1;
73 }
74 _ => {}
75 });
76 Ok(())
77 }
78 CalcValue::Union(_) => unreachable!(),
79 }
80}