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
//! Common error types for this crate.
use std::error;
use std::fmt;
use std::result;

use protobuf;
use protobuf::stream::wire_format;
use serde;

/// A result whose error type is `Error`.
pub type Result<A> = result::Result<A, Error>;

/// An error that may occur when dealing with Protobuf.
#[derive(Debug, Fail)]
pub enum Error {
    /// A native protobuf error.
    #[fail(display = "protobuf error")]
    Protobuf(protobuf::ProtobufError),
    /// The end of stream was reached.
    #[fail(display = "end of stream")]
    EndOfStream,
    /// An unknown enum type was encountered.
    #[fail(display = "unknown enum: {}", name)]
    UnknownEnum {
        /// The name of the enum.
        name: String,
    },
    /// An unknown enum value was encountered.
    #[fail(display = "unknown enum value: {}", value)]
    UnknownEnumValue {
        /// The number of the enum value.
        value: i32,
    },
    /// An unknown message type was encountered.
    #[fail(display = "unknown message: {}", name)]
    UnknownMessage {
        /// The name of the message.
        name: String,
    },
    /// An unexpected wire type was received.
    #[fail(display = "bad wire type: {:?}", wire_type)]
    BadWireType {
        /// The encountered wire type.
        wire_type: wire_format::WireType,
    },
    /// A default value that can't be parsed was received.
    #[fail(display = "bad default value: {:?}", default_value)]
    BadDefaultValue {
        /// The default value that couldn't be parsed.
        default_value: String,
    },
    /// Some user-defined error occurred.
    #[fail(display = "{}", message)]
    Custom {
        /// The user-defined error message.
        message: String,
    },
}

/// A result whose error type is `CompatError`.
pub type CompatResult<A> = result::Result<A, CompatError>;

/// A compatibility error for use with `serde`.
#[derive(Debug)]
pub struct CompatError(failure::Compat<Error>);

impl From<protobuf::error::ProtobufError> for Error {
    fn from(e: protobuf::error::ProtobufError) -> Self {
        Error::Protobuf(e)
    }
}

impl CompatError {
    /// Converts this compatibility error into the underlying error.
    pub fn into_error(self) -> Error {
        self.0.into_inner()
    }
}

impl fmt::Display for CompatError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self.0.fmt(f)
    }
}

impl error::Error for CompatError {}

impl From<Error> for CompatError {
    fn from(e: Error) -> Self {
        use failure::Fail;
        CompatError(e.compat())
    }
}

impl serde::de::Error for CompatError {
    fn custom<T>(msg: T) -> CompatError
    where
        T: fmt::Display,
    {
        use failure::Fail;
        CompatError(
            Error::Custom {
                message: msg.to_string(),
            }
            .compat(),
        )
    }
}