kecc/
utils.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#[macro_export]
/// Ok or exiting the process.
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]
/// Some or exiting the process.
macro_rules! some_or_exit {
    ($e:expr_2021, $code:expr_2021) => {{
        match $e {
            Some(r) => r,
            None => ::std::process::exit($code),
        }
    }};
}

/// Translates `S` to [`Translate::Target`].
// TODO: Should this be in utils?
pub trait Translate<S> {
    /// The type to translate to.
    type Target;

    /// The error type.
    type Error;

    /// Translate `source` to `Self::Target`.
    fn translate(&mut self, source: &S) -> Result<Self::Target, Self::Error>;
}

/// Trait to check if a type can be translated.
pub trait AssertSupported {
    /// Assert that the type can be translated.
    ///
    /// # Panics
    ///
    /// Panics if the type can't be translated.
    // TODO: should return a boolean.
    fn assert_supported(&self);
}

/// Essentially the same as [`PartialEq`].
///
/// Exists to check equaility on some foreign types.
pub trait IsEquiv {
    /// See [`PartialEq::eq`].
    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))
    }
}