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())
}
|