use std; /// Like `std::option::Option` but `None` carries a reason why the value /// isn't available. #[derive(Clone, Debug)] pub enum Conditional where C: Clone + std::fmt::Debug, R: Clone + std::fmt::Debug, { Some(C), None(R), } impl Copy for Conditional where C: Copy + Clone + std::fmt::Debug, R: Copy + Clone + std::fmt::Debug, { } impl Eq for Conditional where C: Eq + Clone + std::fmt::Debug, R: Eq + Clone + std::fmt::Debug, { } impl PartialEq for Conditional where C: PartialEq + Clone + std::fmt::Debug, R: PartialEq + Clone + std::fmt::Debug, { fn eq(&self, other: &Conditional) -> bool { use self::Conditional::*; match (self, other) { (Some(a), Some(b)) => a.eq(b), (None(a), None(b)) => a.eq(b), _ => false, } } } impl std::hash::Hash for Conditional where C: std::hash::Hash + Clone + std::fmt::Debug, R: std::hash::Hash + Clone + std::fmt::Debug, { fn hash(&self, state: &mut H) { match self { Conditional::Some(c) => c.hash(state), Conditional::None(r) => r.hash(state), } } } impl Conditional where C: Clone + std::fmt::Debug, R: Copy + Clone + std::fmt::Debug, { pub fn as_ref<'a>(&'a self) -> Conditional<&'a C, R> { match self { Conditional::Some(c) => Conditional::Some(&c), Conditional::None(r) => Conditional::None(*r), } } }