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
//! This module includes several traits.
//!
//! Few traits are re-exported from other crates, few are used as aliases and others are syntactic sugar.

pub use molecule::{
    hex_string,
    prelude::{Builder, Entity, Reader},
};

/// An alias of `unwrap()` to mark where we are really have confidence to do unwrap.
///
/// We can also customize the panic message or do something else in this alias.
pub trait ShouldBeOk<T> {
    /// Unwraps an `Option` or a `Result` with confidence and we assume that it's impossible to fail.
    fn should_be_ok(self) -> T;
}

// Use for Option
impl<T> ShouldBeOk<T> for Option<T> {
    fn should_be_ok(self) -> T {
        self.unwrap_or_else(|| panic!("should not be None"))
    }
}

// Use for verify
impl<T> ShouldBeOk<T> for molecule::error::VerificationResult<T> {
    fn should_be_ok(self) -> T {
        self.unwrap_or_else(|err| panic!("verify slice should be ok, but {}", err))
    }
}

/// An alias of `from_slice(..)` to mark where we are really have confidence to do unwrap on the result of `from_slice(..)`.
pub trait FromSliceShouldBeOk<'r>: Reader<'r> {
    /// Unwraps the result of `from_slice(..)` with confidence and we assume that it's impossible to fail.
    fn from_slice_should_be_ok(slice: &'r [u8]) -> Self;
}

impl<'r, R> FromSliceShouldBeOk<'r> for R
where
    R: Reader<'r>,
{
    fn from_slice_should_be_ok(slice: &'r [u8]) -> Self {
        match Self::from_slice(slice) {
            Ok(ret) => ret,
            Err(err) => panic!(
                "failed to convert from slice: reason: {}; data: 0x{}.",
                err,
                hex_string(slice)
            ),
        }
    }
}

/// A syntactic sugar to convert binary data into rust types.
pub trait Unpack<T> {
    /// Unpack binary data into rust types.
    fn unpack(&self) -> T;
}

/// A syntactic sugar to convert a rust type into binary data.
pub trait Pack<T: Entity> {
    /// Packs a rust type into binary data.
    fn pack(&self) -> T;
}

/// A syntactic sugar to convert a vector of binary data into one binary data.
pub trait PackVec<T: Entity, I: Entity>: IntoIterator<Item = I> {
    /// Packs a vector of binary data into one binary data.
    fn pack(self) -> T;
}