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, 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::>() .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::(); 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()) }