use std::fmt::{Debug, Display};
use std::io;
use std::str::Utf8Error;
use std::string::FromUtf8Error;
use serde::{de, ser};
use crate::format::{Kind, UnknownSpecial};
#[derive(Debug)]
#[non_exhaustive]
pub enum Error {
NotAPot,
IncompatibleVersion,
Message(String),
TrailingBytes,
Eof,
ImpreciseCastWouldLoseData,
Io(io::Error),
SequenceSizeMustBeKnown,
InvalidUtf8(String),
InvalidKind(u8),
UnexpectedKind(Kind, Kind),
UnknownSymbol(u64),
UnsupportedByteCount(Kind, usize),
InvalidAtomHeader,
TooManyBytesRead,
UnknownSpecial(UnknownSpecial),
}
impl Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::NotAPot => f.write_str("not a pot: invalid header"),
Error::IncompatibleVersion => f.write_str("incompatible version"),
Error::Message(message) => f.write_str(message),
Error::TrailingBytes => f.write_str("extra data at end of input"),
Error::Eof => f.write_str("unexpected end of file"),
Error::ImpreciseCastWouldLoseData => f.write_str("numerical data cannot fit"),
Error::Io(io) => write!(f, "io error: {io}"),
Error::SequenceSizeMustBeKnown => {
f.write_str("serializing sequences of unknown size is unsupported")
}
Error::InvalidUtf8(err) => write!(f, "invalid utf8: {err}"),
Error::InvalidKind(kind) => write!(f, "invalid kind: {kind}"),
Error::UnexpectedKind(encountered, expected) => write!(
f,
"encountered atom kind {encountered:?}, expected {expected:?}"
),
Error::UnknownSymbol(sym) => write!(f, "unknown symbol {sym}"),
Error::InvalidAtomHeader => f.write_str("an atom header was incorrectly formatted"),
Error::TooManyBytesRead => {
f.write_str("the deserialized value is larger than the allowed allocation limit")
}
Error::UnsupportedByteCount(kind, count) => {
write!(f, "unexpected {kind:?} byte count ({count})")
}
Error::UnknownSpecial(err) => Display::fmt(err, f),
}
}
}
impl std::error::Error for Error {}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Self {
Self::Io(err)
}
}
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Self::Message(msg.to_string())
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
Self::Message(msg.to_string())
}
}
impl From<Utf8Error> for Error {
fn from(err: Utf8Error) -> Self {
Self::InvalidUtf8(err.to_string())
}
}
impl From<FromUtf8Error> for Error {
fn from(err: FromUtf8Error) -> Self {
Self::InvalidUtf8(err.to_string())
}
}
impl From<UnknownSpecial> for Error {
fn from(err: UnknownSpecial) -> Self {
Self::UnknownSpecial(err)
}
}