use itertools::izip; use core::ops::Deref; #[macro_export] /// Ok or executing the given expression. macro_rules! ok_or { ($e:expr, $err:expr) => {{ match $e { Ok(r) => r, Err(_) => $err, } }}; } #[macro_export] /// Some or executing the given expression. macro_rules! some_or { ($e:expr, $err:expr) => {{ match $e { Some(r) => r, None => $err, } }}; } #[macro_export] /// Ok or exiting the process. macro_rules! ok_or_exit { ($e:expr, $code:expr) => {{ match $e { Ok(r) => r, Err(e) => { eprintln!("{:?}", e); ::std::process::exit($code); } } }}; } #[macro_export] /// Ok or exiting the process. macro_rules! some_or_exit { ($e:expr, $code:expr) => {{ match $e { Some(r) => r, None => ::std::process::exit($code), } }}; } /// TODO(document) pub trait Translate { /// TODO(document) type Target; /// TODO(document) type Error; /// TODO(document) fn translate(&mut self, source: &S) -> Result; } /// TODO(document) pub trait AssertSupported { /// TODO(document) fn assert_supported(&self); } /// TODO(document) pub trait IsEquiv { /// TODO(document) fn is_equiv(&self, other: &Self) -> bool; } impl IsEquiv for Box { fn is_equiv(&self, other: &Self) -> bool { self.deref().is_equiv(other.deref()) } } impl IsEquiv for &T { fn is_equiv(&self, other: &Self) -> bool { (*self).is_equiv(*other) } } impl IsEquiv for Option { fn is_equiv(&self, other: &Self) -> bool { match (self, other) { (Some(lhs), Some(rhs)) => lhs.is_equiv(rhs), (None, None) => true, _ => false, } } } impl IsEquiv for Vec { fn is_equiv(&self, other: &Self) -> bool { self.len() == other.len() && izip!(self, other).all(|(lhs, rhs)| lhs.is_equiv(rhs)) } }