summaryrefslogtreecommitdiffstats
path: root/src/lib.rs
blob: 3437dca5a2f0fba97393552668162ae36da09f24 (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
use std::ops::Range;

pub use crate::{
    error::{Error, Result},
    service::{Service, Status},
};

pub mod error;
pub mod service;

pub fn generate(title: String, mut services: Vec<Service>, template: String) -> String {
    let client = reqwest::blocking::Client::new();

    let [up, down, unknown] = std::thread::scope(|s| {
        let mut handles = Vec::new();
        for service in services.iter_mut() {
            handles.push(s.spawn(|| service.check(client.clone())));
        }

        handles
            .into_iter()
            .map(|h| h.join().expect("Joining thread"))
            .fold([0, 0, 0], |[up, down, unknown], res| match res {
                Ok(true) => [up + 1, down, unknown],
                Ok(false) => [up, down + 1, unknown],
                Err(_) => [up, down, unknown + 1],
            })
    });

    template
        .match_indices("{{services}}")
        .zip(template.match_indices("{{end}}"))
        .map(|(start, stop)| {
            (
                start.0 + start.1.len()..stop.0,
                start.0..stop.0 + stop.1.len(),
            )
        })
        .collect::<Vec<_>>()
        .into_iter()
        .fold(template, |mut template, (Range { start, end }, outer)| {
            let replace_with = services
                .iter()
                .map(|service| {
                    template[start..end]
                        .replace("{name}", &service.name)
                        .replace("{title}", &service.kind.to_string())
                        .replace("{state}", &service.state.to_string())
                        .replace("{level}", &service.state.as_level())
                })
                .collect::<String>();

            template.replace_range(outer, &replace_with);
            template
        })
        .replace("{title}", &title)
        .replace("{status}", if down > 0 { "error" } else { "ok" })
        .replace("{up}", &up.to_string())
        .replace("{down}", &down.to_string())
        .replace("{unknown}", &unknown.to_string())
}