#[macro_export]
macro_rules! ok_or_exit {
($e:expr_2021, $code:expr_2021) => {{
match $e {
Ok(r) => r,
Err(e) => {
eprintln!("{:?}", e);
::std::process::exit($code);
}
}
}};
}
#[macro_export]
macro_rules! some_or_exit {
($e:expr_2021, $code:expr_2021) => {{
match $e {
Some(r) => r,
None => ::std::process::exit($code),
}
}};
}
pub trait Translate<S> {
type Target;
type Error;
fn translate(&mut self, source: &S) -> Result<Self::Target, Self::Error>;
}
pub trait AssertSupported {
fn assert_supported(&self);
}
pub trait IsEquiv {
fn is_equiv(&self, other: &Self) -> bool;
}
impl<T: IsEquiv> IsEquiv for Box<T> {
fn is_equiv(&self, other: &Self) -> bool {
(**self).is_equiv(&**other)
}
}
impl<T: IsEquiv> IsEquiv for &T {
fn is_equiv(&self, other: &Self) -> bool {
(*self).is_equiv(*other)
}
}
impl<T: IsEquiv> IsEquiv for Option<T> {
fn is_equiv(&self, other: &Self) -> bool {
match (self, other) {
(Some(lhs), Some(rhs)) => lhs.is_equiv(rhs),
(None, None) => true,
_ => false,
}
}
}
impl<T: IsEquiv> IsEquiv for Vec<T> {
fn is_equiv(&self, other: &Self) -> bool {
self.len() == other.len() && self.iter().zip(other).all(|(lhs, rhs)| lhs.is_equiv(rhs))
}
}