use crate::handle::handle::TaskHandle;
use crate::tasks::request::TaskRequest;
use std::sync::Arc;
use crate::tasks::response::TaskResponse;
use serde::Deserialize;
use crate::handle::template::BlendTarget;
use crate::playbooks::templar::TemplateMode;
#[derive(Deserialize,Debug,Clone)]
#[serde(deny_unknown_fields)]
pub struct PreLogicInput {
pub condition: Option<String>,
pub subscribe: Option<String>,
pub sudo: Option<String>,
pub items: Option<ItemsInput>,
pub tags: Option<Vec<String>>,
pub delegate_to: Option<String>
}
#[derive(Deserialize,Debug,Clone)]
#[serde(untagged)]
pub enum ItemsInput {
ItemsString(String),
ItemsList(Vec<String>),
}
#[derive(Debug)]
pub struct PreLogicEvaluated {
pub condition: bool,
pub subscribe: Option<String>,
pub sudo: Option<String>,
pub items: Option<ItemsInput>,
pub tags: Option<Vec<String>>
}
#[derive(Deserialize,Debug)]
#[serde(deny_unknown_fields)]
pub struct PostLogicInput {
pub notify: Option<String>,
pub ignore_errors: Option<String>,
pub retry: Option<String>,
pub delay: Option<String>
}
#[derive(Debug)]
pub struct PostLogicEvaluated {
pub notify: Option<String>,
pub ignore_errors: bool,
pub retry: u64,
pub delay: u64,
}
impl PreLogicInput {
pub fn template(handle: &TaskHandle, request: &Arc<TaskRequest>, tm: TemplateMode, input: &Option<Self>) -> Result<Option<PreLogicEvaluated>,Arc<TaskResponse>> {
if input.is_none() {
return Ok(None);
}
let input2 = input.as_ref().unwrap();
return Ok(Some(PreLogicEvaluated {
condition: match &input2.condition {
Some(cond2) => handle.template.test_condition(request, tm, cond2)?,
None => true
},
sudo: handle.template.string_option_no_spaces(request, tm, &String::from("sudo"), &input2.sudo)?,
subscribe: handle.template.no_template_string_option_trim(&input2.subscribe),
items: input2.items.clone(),
tags: input2.tags.clone()
}));
}
}
impl PostLogicInput {
pub fn template(handle: &TaskHandle, request: &Arc<TaskRequest>, tm: TemplateMode, input: &Option<Self>) -> Result<Option<PostLogicEvaluated>,Arc<TaskResponse>> {
if input.is_none() {
return Ok(None);
}
let input2 = input.as_ref().unwrap();
return Ok(Some(PostLogicEvaluated {
notify: handle.template.string_option_trim(request, tm, &String::from("notify"), &input2.notify)?,
delay: handle.template.integer_option(request, tm, &String::from("delay"), &input2.delay, 1)?,
ignore_errors: handle.template.boolean_option_default_false(request, tm, &String::from("ignore_errors"), &input2.ignore_errors)?,
retry: handle.template.integer_option(request, tm, &String::from("retry"), &input2.retry, 0)?,
}));
}
}
pub fn template_items(handle: &Arc<TaskHandle>, request: &Arc<TaskRequest>, tm: TemplateMode, items_input: &Option<ItemsInput>)
-> Result<Vec<serde_yaml::Value>, Arc<TaskResponse>> {
return match items_input {
None => Ok(empty_items_vector()),
Some(ItemsInput::ItemsString(x)) => {
let blended = handle.run_state.context.read().unwrap().get_complete_blended_variables(
&handle.host,
BlendTarget::NotTemplateModule
);
match blended.contains_key(&x) {
true => {
let value : serde_yaml::Value = blended.get(&x).unwrap().clone();
match value {
serde_yaml::Value::Sequence(vs) => template_serde_sequence(handle, request, tm, vs),
_ => {
return Err(handle.response.is_failed(request, &format!("with/items variable did not resolve to a list")));
}
}
},
false => {
return Err(handle.response.is_failed(request, &format!("variable not found for items: {}", x)))
}
}
},
Some(ItemsInput::ItemsList(x)) => {
let mut output : Vec<serde_yaml::Value> = Vec::new();
for item in x.iter() {
output.push(serde_yaml::Value::String(handle.template.string(request, tm, &String::from("items"), item)?));
}
Ok(output)
}
}
}
pub fn empty_items_vector() -> Vec<serde_yaml::Value> {
return vec![serde_yaml::Value::Bool(true)];
}
pub fn template_serde_sequence(
handle: &TaskHandle,
request: &Arc<TaskRequest>,
tm: TemplateMode,
vs: serde_yaml::Sequence)
-> Result<Vec<serde_yaml::Value>,Arc<TaskResponse>> {
let mut output : Vec<serde_yaml::Value> = Vec::new();
for seq_item in vs.iter() {
match seq_item {
serde_yaml::Value::String(x) => {
output.push(serde_yaml::Value::String(handle.template.string(request, tm, &String::from("items"), x)?))
},
x => { output.push(x.clone()) }
}
}
return Ok(output);
}