use crate::core::{Result, Host};
use serde_json::{json, Value};
pub type TaskResult = Result<Value>;
pub trait Task<Data> {
fn prepare(&self, host: Host) -> Result<Data>;
fn apply(&self, host: Host, data: Data) -> TaskResult;
}
pub trait TaskRunner {
fn run_task_seq<Data>(&self, task: &dyn Task<Data>) -> TaskResult;
}
impl TaskRunner for Vec<Host> {
fn run_task_seq<Data>(&self, task: &dyn Task<Data>) -> TaskResult {
let results: Vec<Value> = self
.into_iter()
.map(|host| {
let data = task.prepare(host.clone())?;
Ok((host, data))
})
.collect::<Result<Vec<(&Host, Data)>>>()?
.into_iter()
.map(|(host, data)| {
task.apply(host.clone(), data)
.map_or_else(
|err| json!({
"host": host.id,
"success": false,
"error": format!("{}", err),
}),
|info| json!({
"host": host.id,
"success": true,
"info": info,
})
)
})
.collect();
Ok(json!(results))
}
}
pub mod exec;
pub mod info;
pub mod upload;
pub mod download;