#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Outcome<H, A> {
Refined(H),
Abstain(A),
}
impl<H, A> Outcome<H, A> {
pub fn map<B, F>(self, f: F) -> Outcome<B, A>
where
F: FnOnce(H) -> B,
{
match self {
Outcome::Refined(h) => Outcome::Refined(f(h)),
Outcome::Abstain(a) => Outcome::Abstain(a),
}
}
pub fn and_then<B, F>(self, f: F) -> Outcome<B, A>
where
F: FnOnce(H) -> Outcome<B, A>,
{
match self {
Outcome::Refined(h) => f(h),
Outcome::Abstain(a) => Outcome::Abstain(a),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_map_refined() {
let outcome: Outcome<u64, &str> = Outcome::Refined(5);
let mapped = outcome.map(|x| x * 2);
assert_eq!(mapped, Outcome::Refined(10));
}
#[test]
fn test_map_abstain() {
let outcome: Outcome<u64, &str> = Outcome::Abstain("insufficient data");
let mapped = outcome.map(|x| x * 2);
assert_eq!(mapped, Outcome::Abstain("insufficient data"));
}
#[test]
fn test_and_then_refined() {
let outcome: Outcome<u64, &str> = Outcome::Refined(5);
let chained = outcome.and_then(|x| Outcome::Refined(x * 2));
assert_eq!(chained, Outcome::Refined(10));
}
#[test]
fn test_and_then_abstain() {
let outcome: Outcome<u64, &str> = Outcome::Abstain("insufficient data");
let chained = outcome.and_then(|_| Outcome::Refined(10));
assert_eq!(chained, Outcome::Abstain("insufficient data"));
}
}