nettext/src/dec/error.rs

72 lines
2.4 KiB
Rust

use err_derive::Error;
use crate::dec::debug;
/// The type of errors returned by helper functions on `Term`
#[derive(Debug, Clone, Error)]
pub enum TypeError {
/// The term could not be decoded in the given type
#[error(display = "Not a {}", _0)]
WrongType(&'static str),
/// The term is not an array of the requested length
#[error(display = "Expected {} items, got {}", _0, _1)]
WrongLength(usize, usize),
/// The dictionnary is missing a key
#[error(display = "Missing key `{}` in dict", _0)]
MissingKey(String),
/// The dictionnary contains an invalid key
#[error(display = "Spurrious/unexpected key `{}` in dict", _0)]
UnexpectedKey(String),
/// The underlying raw string contains garbage (should not happen in theory)
#[error(display = "Garbage in underlying data")]
Garbage,
}
impl From<std::str::Utf8Error> for TypeError {
fn from(_x: std::str::Utf8Error) -> TypeError {
TypeError::Garbage
}
}
// ----
/// The error kind returned by the `decode` function.
#[derive(Eq, PartialEq)]
pub enum DecodeError<'a> {
/// Indicates that there is trailing garbage at the end of the decoded string
Garbage(&'a [u8]),
/// Indicates that the entered string does not represent a complete nettext term
IncompleteInput,
/// Indicates a syntax error in the decoded term
NomError(&'a [u8], nom::error::ErrorKind),
}
impl<'a> std::fmt::Display for DecodeError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
match self {
DecodeError::Garbage(g) => write!(f, "Garbage: `{}`", debug(g)),
DecodeError::IncompleteInput => write!(f, "Incomplete input"),
DecodeError::NomError(s, e) => write!(f, "Nom: {:?}, at: `{}`", e, debug(s)),
}
}
}
impl<'a> std::fmt::Debug for DecodeError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
std::fmt::Display::fmt(self, f)
}
}
impl<'a> std::error::Error for DecodeError<'a> {}
impl<'a> From<nom::Err<nom::error::Error<&'a [u8]>>> for DecodeError<'a> {
fn from(e: nom::Err<nom::error::Error<&'a [u8]>>) -> DecodeError<'a> {
match e {
nom::Err::Incomplete(_) => DecodeError::IncompleteInput,
nom::Err::Error(e) | nom::Err::Failure(e) => DecodeError::NomError(e.input, e.code),
}
}
}