use std::fmt::{self, Display, Debug, Formatter};
use std::error::Error;
use super::{MsgPack};
pub struct ConversionError {
pub original: MsgPack,
pub attempted: &'static str,
}
impl Display for ConversionError {
fn fmt (&self, f: &mut Formatter) -> fmt::Result {
let original_type = match self.original {
MsgPack::Nil => "nil",
MsgPack::Int(_) => "int",
MsgPack::Uint(_) => "uint",
MsgPack::Float(_) => "float",
MsgPack::Boolean(_) => "boolean",
MsgPack::String(_) => "string",
MsgPack::Binary(_) => "binary",
MsgPack::Array(_) => "array",
MsgPack::Map(_) => "map",
MsgPack::Extension(_) => "extension",
};
write!(f, "MsgPack conversion error: cannot use {} as {}", original_type, self.attempted)
}
}
impl Debug for ConversionError {
fn fmt (&self, f: &mut Formatter) -> fmt::Result {
let original_type = match self.original {
MsgPack::Nil => "nil",
MsgPack::Int(_) => "int",
MsgPack::Uint(_) => "uint",
MsgPack::Float(_) => "float",
MsgPack::Boolean(_) => "boolean",
MsgPack::String(_) => "string",
MsgPack::Binary(_) => "binary",
MsgPack::Array(_) => "array",
MsgPack::Map(_) => "map",
MsgPack::Extension(_) => "extension",
};
write!(f, "MsgPack conversion error: cannot use {} as {} (original value: {:?})", original_type, self.attempted, self.original)
}
}
impl Error for ConversionError {}
impl ConversionError {
pub fn recover (self) -> MsgPack {
self.original
}
}
pub struct ParseError {
pub byte: usize
}
impl Display for ParseError {
fn fmt (&self, f: &mut Formatter) -> fmt::Result {
write!(f, "MsgPack parse error at byte {}", self.byte)
}
}
impl Debug for ParseError {
fn fmt (&self, f: &mut Formatter) -> fmt::Result {
write!(f, "MsgPack parse error at byte {}", self.byte)
}
}
impl Error for ParseError {}
impl ParseError {
pub fn offset (&self, value: usize) -> ParseError {
ParseError { byte: self.byte + value }
}
pub fn offset_result <T> (result: Result<T, ParseError>, value: usize) -> Result<T, ParseError> {
result.map_err(|err| err.offset(value))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn conversion_error () {
let error = ConversionError { original: MsgPack::Float(4.2), attempted: "int" };
let error_message = format!("{}", error);
assert_eq!(error_message, "MsgPack conversion error: cannot use float as int");
let recovered = error.recover();
assert!(recovered.is_float());
assert_eq!(recovered.as_float().unwrap(), 4.2);
}
#[test]
fn parse_error () {
let error = ParseError { byte: 42 };
let error_message = format!("{}", error);
assert_eq!(error_message, "MsgPack parse error at byte 42");
}
}