use crate::error::Error;
use crate::modules::prelude::*;
use crate::task::moduleblock::ModuleBlockExpectedState;
use serde::{Deserialize, Deserializer, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Step {
pub name: Option<String>,
pub run_as: Option<String>,
pub with_sudo: Option<bool>,
pub with_sudo_rs: Option<bool>,
pub allowed_to_fail: Option<bool>,
pub register: Option<String>,
pub moduleblock: ModuleBlockExpectedState,
}
impl Step {
pub fn from_parsed_step(parsed_step: ParsingStep) -> Result<Step, Error> {
parsed_step.parsemodule()
}
pub fn check(&self) -> Result<(), Error> {
if let Err(error_detail) = self.moduleblock.check() {
return Err(error_detail);
}
Ok(())
}
}
fn deserialize_argumentlessmodule<'a, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
where
T: Deserialize<'a>,
D: Deserializer<'a>,
{
Deserialize::deserialize(deserializer).map(Some)
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ParsingStep {
pub name: Option<String>,
pub run_as: Option<String>,
pub with_sudo: Option<bool>,
pub with_sudo_rs: Option<bool>,
pub allowed_to_fail: Option<bool>,
pub register: Option<String>,
pub service: Option<ServiceBlockExpectedState>,
pub debug: Option<DebugBlockExpectedState>,
pub lineinfile: Option<LineInFileBlockExpectedState>,
pub command: Option<CommandBlockExpectedState>,
pub apt: Option<AptBlockExpectedState>,
pub pacman: Option<PacmanBlockExpectedState>,
pub dnf: Option<YumDnfBlockExpectedState>,
#[serde(default, deserialize_with = "deserialize_argumentlessmodule")]
pub ping: Option<Option<PingBlockExpectedState>>, pub yum: Option<YumDnfBlockExpectedState>,
}
impl ParsingStep {
pub fn parsemodule(&self) -> Result<Step, Error> {
let mut counter: u8 = 0;
let mut moduleblock: Option<ModuleBlockExpectedState> = None;
if let Some(content) = self.service.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Service(content));
}
if let Some(content) = self.debug.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Debug(content));
}
if let Some(content) = self.lineinfile.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::LineInFile(content));
}
if let Some(content) = self.command.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Command(content));
}
if let Some(content) = self.apt.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Apt(content));
}
if let Some(content) = self.pacman.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Pacman(content));
}
if let Some(content) = self.dnf.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Dnf(content));
}
if let Some(_content) = self.ping.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Ping(PingBlockExpectedState {}));
}
if let Some(content) = self.yum.clone() {
counter += 1;
moduleblock = Some(ModuleBlockExpectedState::Yum(content));
}
if counter > 1 {
return Err(Error::FailedInitialization(
"Too much modules defined in this step. Only one module per step please.".into(),
));
} else {
match moduleblock {
Some(module_block_expected_state) => {
if let (Some(true), Some(true)) = (self.with_sudo, self.with_sudo_rs) {
return Err(Error::FailedInitialization(
"Paramaters with_sudo and with_sudo_rs are mutually exclusive".into(),
));
}
return Ok(Step {
name: self.name.clone(),
run_as: self.run_as.clone(),
with_sudo: self.with_sudo.clone(),
with_sudo_rs: self.with_sudo_rs.clone(),
allowed_to_fail: self.allowed_to_fail.clone(),
register: self.register.clone(),
moduleblock: module_block_expected_state,
});
}
None => {
return Err(Error::FailedInitialization(
"No module found in this step".into(),
));
}
}
}
}
}