use crate::tasks::*;
use crate::handle::handle::TaskHandle;
use serde::Deserialize;
use std::sync::Arc;
const MODULE: &str = "assert";
#[derive(Deserialize,Debug)]
#[serde(deny_unknown_fields)]
pub struct AssertTask {
pub name: Option<String>,
pub msg: Option<String>,
pub r#true: Option<String>,
pub r#false: Option<String>,
pub all_true: Option<Vec<String>>,
pub all_false: Option<Vec<String>>,
pub some_true: Option<Vec<String>>,
pub with: Option<PreLogicInput>,
pub and: Option<PostLogicInput>
}
#[allow(dead_code)]
struct AssertAction {
pub name: String,
pub msg: Option<String>,
pub r#true: bool,
pub r#false: bool,
pub all_true: Vec<bool>,
pub all_false: Vec<bool>,
pub some_true: Vec<bool>
}
impl IsTask for AssertTask {
fn get_module(&self) -> String { String::from(MODULE) }
fn get_name(&self) -> Option<String> { self.name.clone() }
fn get_with(&self) -> Option<PreLogicInput> { self.with.clone() }
fn evaluate(&self, handle: &Arc<TaskHandle>, request: &Arc<TaskRequest>, tm: TemplateMode) -> Result<EvaluatedTask, Arc<TaskResponse>> {
return Ok(
EvaluatedTask {
action: Arc::new(AssertAction {
name: self.name.clone().unwrap_or(String::from(MODULE)),
msg: handle.template.string_option_unsafe_for_shell(request, tm, &String::from("msg"), &self.msg)?,
r#true: match self.r#true.is_some() {
true => handle.template.test_condition(request, tm, &self.r#true.as_ref().unwrap())?,
false => true
},
r#false: match self.r#false.is_some() {
true => handle.template.test_condition(request, tm, &self.r#false.as_ref().unwrap())?,
false => false
},
all_true: match self.all_true.is_some() {
true => eval_list(handle, request, tm, self.all_true.as_ref().unwrap())?,
false => vec![true]
},
all_false: match self.all_false.is_some() {
true => eval_list(handle, request, tm, self.all_false.as_ref().unwrap())?,
false => vec![false]
},
some_true: match self.some_true.is_some() {
true => eval_list(handle, request, tm, self.some_true.as_ref().unwrap())?,
false => vec![true]
}
}),
with: Arc::new(PreLogicInput::template(handle, request, tm, &self.with)?),
and: Arc::new(PostLogicInput::template(handle, request, tm, &self.and)?),
}
);
}
}
fn eval_list(handle: &Arc<TaskHandle>, request: &Arc<TaskRequest>, tm: TemplateMode, list: &Vec<String>) -> Result<Vec<bool>,Arc<TaskResponse>> {
let mut results : Vec<bool> = Vec::new();
for item in list.iter() {
results.push(handle.template.test_condition(request, tm, item)?);
}
return Ok(results);
}
impl IsAction for AssertAction {
fn dispatch(&self, handle: &Arc<TaskHandle>, request: &Arc<TaskRequest>) -> Result<Arc<TaskResponse>, Arc<TaskResponse>> {
match request.request_type {
TaskRequestType::Query => {
return Ok(handle.response.needs_passive(request));
},
TaskRequestType::Passive => {
let mut fail = false;
if self.r#true == false {
fail = true;
}
else if self.r#false == true {
fail = true;
}
else if self.all_true.contains(&false) {
fail = true;
}
else if self.all_false.contains(&true) {
fail = true;
}
else if ! self.some_true.contains(&true) {
fail = true;
}
if fail {
if self.msg.is_some() {
return Err(handle.response.is_failed(request, &format!("assertion failed: {}", self.msg.as_ref().unwrap())));
} else {
return Err(handle.response.is_failed(request, &format!("assertion failed")));
}
}
return Ok(handle.response.is_passive(request));
},
_ => { return Err(handle.response.not_supported(request)); }
}
}
}