aboutsummaryrefslogtreecommitdiff
path: root/src/templates.rs
blob: 7e3753a3edd502285d3976c9703062bb225b0299 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use serde::Serialize;
use serde_json::json;
use serde_json::value::Value;
use std::collections::HashMap;
use tera::Tera;
use tera::{Error, Result};

use crate::queries;

#[derive(Debug, Serialize)]
pub enum Header {
    Payments,
    Categories,
    Incomes,
    Balance,
    Statistics,
}

pub fn get() -> Tera {
    let mut tera = match Tera::new("templates/**/*") {
        Ok(t) => t,
        Err(e) => {
            error!("Parsing error(s): {}", e);
            ::std::process::exit(1);
        }
    };
    tera.register_function("payments_params", payments_params);
    tera.register_filter("numeric", numeric);
    tera.register_filter("euros", euros);
    tera
}

fn payments_params(args: &HashMap<String, Value>) -> Result<Value> {
    let q = json!({
        "page": args.get("page"),
        "search": args.get("search"),
        "frequency": args.get("frequency"),
        "highlight": args.get("highlight"),
    });

    match serde_json::from_value(q) {
        Ok(q) => Ok(json!(queries::payments_url(q))),
        Err(msg) => Err(Error::msg(msg)),
    }
}

fn euros(value: &Value, _: &HashMap<String, Value>) -> Result<Value> {
    match value {
        Value::Number(n) => {
            if let Some(n) = n.as_i64() {
                let str = rgrouped(n.abs().to_string(), 3).join(" ");
                let sign = if n < 0 { "-" } else { "" };
                Ok(json!(format!("{}{} €", sign, str)))
            } else if let Some(n) = n.as_f64() {
                Ok(json!(format!("{} €", n.to_string())))
            } else {
                Err(Error::msg("Error parsing number"))
            }
        }
        _ => Err(Error::msg(format!("{:?} should be a number", value))),
    }
}

fn numeric(value: &Value, _: &HashMap<String, Value>) -> Result<Value> {
    match value {
        Value::Number(n) => {
            if let Some(n) = n.as_i64() {
                let str = rgrouped(n.abs().to_string(), 3).join(" ");
                let sign = if n < 0 { "-" } else { "" };
                Ok(json!(format!("{}{}", sign, str)))
            } else if let Some(n) = n.as_f64() {
                Ok(json!(format!("{}", n.to_string())))
            } else {
                Err(Error::msg("Error parsing number"))
            }
        }
        _ => Err(Error::msg(format!("{:?} should be a number", value))),
    }
}

fn rgrouped(str: String, n: usize) -> Vec<String> {
    let mut str = str.clone();
    let mut l = str.len();
    let mut res = vec![];
    while l > n {
        let str2 = str.clone();
        let (start, end) = str2.split_at(l - n);
        l -= n;
        str = start.to_string();
        res.push(end.to_string());
    }
    if !str.is_empty() {
        res.push(str);
    }
    res.reverse();
    res
}