Skip to content

Commit

Permalink
chore: extract step initializer logic to mod
Browse files Browse the repository at this point in the history
  • Loading branch information
rawkode committed May 21, 2021
1 parent 0d38f7f commit 2aa7777
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 27 deletions.
30 changes: 3 additions & 27 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,32 +331,8 @@ fn main() -> anyhow::Result<()> {
let mut steps = action
.plan(&m1, &contexts)
.into_iter()
.filter(|step| {
step.initializers
.iter()
.fold(true, |_, flow_control| match flow_control {
steps::initializers::FlowControl::SkipIf(i) => {
match i.initialize() {
Ok(true) => {
// Returning false because we should Skip if true, so false
// will filter this out of the atom list
return false;
}
Ok(false) => true,
Err(e) => {
error!(
"Failed to run initializer on Atom: {}",
e.to_string()
);
// On an error, we can't really determine if this Atom should
// run; so lets play it safe and filter it out too
return false;
}
}
}
})
})
.filter(|action_atom| action_atom.atom.plan())
.filter(|step| step.do_initializers_allow_us_to_run())
.filter(|step| step.atom.plan())
.peekable();

if steps.peek().is_none() {
Expand All @@ -371,7 +347,7 @@ fn main() -> anyhow::Result<()> {
continue;
}

match action_atom.atom.execute() {
match step.atom.execute() {
Ok(_) => continue,
Err(err) => {
debug!("Atom failed to execute: {:?}", err);
Expand Down
24 changes: 24 additions & 0 deletions src/steps/initializers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,27 @@ pub enum FlowControl {
pub trait Initializer {
fn initialize(&self) -> anyhow::Result<bool>;
}

#[cfg(test)]
pub(crate) mod test {
use super::Initializer;
use anyhow::anyhow;

#[derive(Clone, Debug)]
pub struct Echo(pub bool);

impl Initializer for Echo {
fn initialize(&self) -> anyhow::Result<bool> {
Ok(self.0)
}
}

#[derive(Clone, Debug)]
pub struct Error();

impl Initializer for Error {
fn initialize(&self) -> anyhow::Result<bool> {
Err(anyhow!("ErrorInitializer"))
}
}
}
89 changes: 89 additions & 0 deletions src/steps/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::atoms::Atom;
use std::fmt::Display;
use tracing::error;

pub mod finalizers;
pub mod initializers;
Expand All @@ -19,3 +20,91 @@ impl Display for Step {
)
}
}

impl Step {
pub fn do_initializers_allow_us_to_run(&self) -> bool {
self.initializers
.iter()
.fold(true, |_, flow_control| match flow_control {
initializers::FlowControl::SkipIf(i) => {
match i.initialize() {
Ok(true) => {
// Returning false because we should Skip if true, so false
// will filter this out of the atom list
return false;
}
Ok(false) => true,
Err(err) => {
error!("Failed to run initializer: {}", err.to_string());

// On an error, we can't really determine if this Atom should
// run; so lets play it safe and filter it out too
return false;
}
}
}
})
}
}

#[cfg(test)]
mod tests {
use super::initializers::test::Echo as EchoInitializer;
use super::initializers::test::Error as ErrorInitializer;
use super::initializers::FlowControl;
use crate::atoms::Echo as EchoAtom;

use super::*;

#[test]
fn initializers_can_control_execution() {
let step = Step {
atom: Box::new(EchoAtom("hello-world")),
initializers: vec![FlowControl::SkipIf(Box::new(EchoInitializer(true)))],
finalizers: vec![],
};

assert_eq!(false, step.do_initializers_allow_us_to_run());

let step = Step {
atom: Box::new(EchoAtom("hello-world")),
initializers: vec![FlowControl::SkipIf(Box::new(EchoInitializer(false)))],
finalizers: vec![],
};

assert_eq!(true, step.do_initializers_allow_us_to_run());

let step = Step {
atom: Box::new(EchoAtom("hello-world")),
initializers: vec![
FlowControl::SkipIf(Box::new(EchoInitializer(false))),
FlowControl::SkipIf(Box::new(EchoInitializer(true))),
],
finalizers: vec![],
};

assert_eq!(false, step.do_initializers_allow_us_to_run());
}

#[test]
fn initializers_that_error_block_execution() {
let step = Step {
atom: Box::new(EchoAtom("hello-world")),
initializers: vec![FlowControl::SkipIf(Box::new(ErrorInitializer()))],
finalizers: vec![],
};

assert_eq!(false, step.do_initializers_allow_us_to_run());

let step = Step {
atom: Box::new(EchoAtom("hello-world")),
initializers: vec![
FlowControl::SkipIf(Box::new(EchoInitializer(false))),
FlowControl::SkipIf(Box::new(ErrorInitializer())),
],
finalizers: vec![],
};

assert_eq!(false, step.do_initializers_allow_us_to_run());
}
}

0 comments on commit 2aa7777

Please sign in to comment.