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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use {
    failure::{Compat, Fail},
    serde::ser,
    std::{
        error,
        fmt::{self, Display, Formatter},
        io, result,
    },
};

/// Error during serialization.
#[derive(Debug, Fail)]
pub enum SerializationError {
    /// Custom error message.
    #[fail(display = "custom error message: {}", message)]
    Custom {
        /// The message of the custom error.
        message: String,
    },

    /// Failure to serialize a value.
    #[fail(display = "failed to serialize {}", what)]
    Failure {
        /// A description of what was being serialized.
        what: String,
        /// The error that ocurred during serialization.
        #[cause]
        cause: Box<CompatSerializationError>,
    },

    /// IO error while serializing a value.
    #[fail(display = "IO error while serializing {}: {}", what, cause)]
    IoError {
        /// A description of what was being serialized.
        what: String,
        /// The error that ocurred during serialization.
        #[cause]
        cause: io::Error,
    },

    /// Map types are not supported by XDR.
    #[fail(display = "XDR does not support a map type")]
    MapIsNotSupported,

    /// Attempt to serialize opaque data with too many bytes.
    #[fail(display = "opaque data is too long: {} bytes", length)]
    OpaqueDataIsTooLong {
        /// The length of the data, which is larger than what can be
        /// represented.
        length: usize,
    },

    /// Fatal error while serializing a sequence or a tuple.
    ///
    /// This is probably caused by ignoring a previous error.
    #[fail(display = "fatal failure while serializing {}", type_name)]
    SequenceOrTupleFatalError {
        /// The name of the type being serialized.
        type_name: String,
    },

    /// Fatal error while serializing an object.
    ///
    /// This is probably caused by ignoring a previous error.
    #[fail(display = "fatal failure while serializing struct: {}", name)]
    StructFatalError {
        /// The name of the type being serialized.
        name: String,
    },

    /// Attempt to serialize a sequence that's too long.
    #[fail(display = "sequence is too long to be serialized: {}", length)]
    SequenceTooLong {
        /// The length of the sequence, which is larger than what can be
        /// represented.
        length: usize,
    },

    /// Sequences with unknown lengths are not supported.
    #[fail(display = "can't serialize sequence with unknown length")]
    SequenceWithUnknownLength,

    /// Only ASCII strings can be serialized.
    #[fail(display = "string is not ASCII encoded: {}", string)]
    StringIsNotAscii {
        /// The string that can't be represented as an ASCII string.
        string: String,
    },

    /// Attempt to serialize a string that's too long.
    #[fail(display = "string is too long: {}", string)]
    StringIsTooLong {
        /// The length of the string, which is larger than what can be
        /// represented.
        string: String,
    },
}

/// An `Error`-compatible wrapper for `SerializationError`.
///
/// Contains helper methods to convert to and from the wrapped type.
#[derive(Debug)]
pub struct CompatSerializationError(Compat<SerializationError>);

impl From<SerializationError> for CompatSerializationError {
    fn from(error: SerializationError) -> Self {
        CompatSerializationError(error.compat())
    }
}

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

impl error::Error for CompatSerializationError {
    fn description(&self) -> &str {
        self.0.description()
    }
}

impl ser::Error for CompatSerializationError {
    fn custom<T: Display>(message: T) -> Self {
        let error = SerializationError::Custom {
            message: message.to_string(),
        };

        CompatSerializationError(error.compat())
    }
}

impl From<CompatSerializationError> for SerializationError {
    fn from(wrapped_error: CompatSerializationError) -> Self {
        match wrapped_error {
            CompatSerializationError(error) => error.into_inner(),
        }
    }
}

pub type Result<T> = result::Result<T, CompatSerializationError>;