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
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
use ascii;
use std::fmt;
use std::result;
use crate::tag::TagClass;

/// Result that encapsulates the Error type of this library
pub type Result<T> = result::Result<T, Error>;

/// Error in ASN1-DER parse/build operations
#[derive(Clone, Debug, PartialEq)]
pub enum Error {
    /// Tag cannot be parsed because there are no data
    EmptyTag(TagClass),

    /// All data was consumed but tag length octets did not finished (high tag number form)
    NotEnoughTagOctets(TagClass),

    /// Tag parsed is not the expected for the type
    UnmatchedTag(TagClass),

    /// No length was provided
    LengthEmpty,

    /// The size of the length is higher than the available octets
    NotEnoughLengthOctects,

    /// No value was provided to build
    NoValue,

    /// No found component with the identifier specified
    NoComponent,

    /// Error in a field of a sequence
    SequenceFieldError(String, String, Box<Error>),

    /// Error while processing a sequence
    SequenceError(String, Box<Error>),

    /// There are no enough data provided for the length specified
    NoDataForLength,

    /// There are octets which were not consumed in decoding
    NoAllDataConsumed,

    /// Problem with received value, such as format or expected length
    IncorrectValue(String),

    /// Error formating non-utf8 characters
    Utf8Error,

    /// Error formating non-utf8 characters
    AsciiError,

    /// Error parsing to int
    ParseIntError,

    /// Error in value due to limitation of the implementation
    ImplementationError(String),

    /// Error in value due to a constraint in the type
    ConstraintError(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl From<std::str::Utf8Error> for Error {
    fn from(_inner: std::str::Utf8Error) -> Self {
        return Self::Utf8Error;
    }
}

impl From<std::string::FromUtf8Error> for Error {
    fn from(_inner: std::string::FromUtf8Error) -> Self {
        return Self::Utf8Error;
    }
}

impl From<std::num::ParseIntError> for Error {
    fn from(_inner: std::num::ParseIntError) -> Self {
        return Self::ParseIntError;
    }
}

impl From<ascii::ToAsciiCharError> for Error {
    fn from(_inner: ascii::ToAsciiCharError) -> Self {
        return Self::AsciiError;
    }
}


#[cfg(test)]
mod test {
    use super::*;
    use crate::tag::TagClass;

    #[test]
    fn raise_empty_tag_error() {
        let error_kind = super::Error::from(Error::EmptyTag(TagClass::Context));

        match error_kind {
            Error::EmptyTag(tag_class) => assert_eq!(TagClass::Context, tag_class),
            _ => unreachable!(),
        }
    }
}