diff --git a/01.workspace/oxidice_lib/src/imp/mod.rs b/01.workspace/oxidice_lib/src/imp/mod.rs index 9039b76..c75e913 100644 --- a/01.workspace/oxidice_lib/src/imp/mod.rs +++ b/01.workspace/oxidice_lib/src/imp/mod.rs @@ -2,3 +2,4 @@ pub mod die_new; pub mod die_roll; pub mod handful_grab; pub mod handful_roll; +pub mod outcome_sum; diff --git a/01.workspace/oxidice_lib/src/imp/outcome_sum.rs b/01.workspace/oxidice_lib/src/imp/outcome_sum.rs new file mode 100644 index 0000000..099f7e9 --- /dev/null +++ b/01.workspace/oxidice_lib/src/imp/outcome_sum.rs @@ -0,0 +1,37 @@ +use crate::*; + +fn sum_of(values: Vec) -> Result { + if values.is_empty() { + return Ok(Outcome::Scalar(0)); + } + let mut ret = Ok(Outcome::Scalar(0)); + for value in values { + ret = ret.and_then(|outcome: Outcome| match outcome { + Outcome::List(_) => Err(FailedTo::ProcessInput), + Outcome::Scalar(acc) => acc + .checked_add(value) + .map(|new_acc: u16| Outcome::Scalar(new_acc)) + .ok_or(FailedTo::SumValues), + }) + } + ret +} + +impl Outcome { + pub fn sum(self) -> Result { + match self { + Outcome::Scalar(value) => Ok(Outcome::Scalar(value)), + Outcome::List(values) => sum_of(values), + } + } +} + +#[cfg(test)] +mod unit_tests { + use super::*; + #[test] + fn check_sum() { + let outcome = Handful::grab(5, 1).roll().sum(); + assert_eq!(outcome, Ok(Outcome::Scalar(5))); + } +} diff --git a/01.workspace/oxidice_lib/src/str/failed_to.rs b/01.workspace/oxidice_lib/src/str/failed_to.rs index 49e8906..01cb888 100644 --- a/01.workspace/oxidice_lib/src/str/failed_to.rs +++ b/01.workspace/oxidice_lib/src/str/failed_to.rs @@ -3,7 +3,10 @@ use crate::*; // use std::str::FromStr; #[derive(Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Copy, Hash)] -pub enum E {} +pub enum E { + ProcessInput, + SumValues, +} // impl Display for E { // fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {