pot/
error.rs

1use std::fmt::{Debug, Display};
2use std::io;
3use std::str::Utf8Error;
4use std::string::FromUtf8Error;
5
6use serde::{de, ser};
7
8use crate::format::{Kind, UnknownSpecial};
9
10/// All errors that Pot may return.
11#[derive(Debug)]
12#[non_exhaustive]
13pub enum Error {
14    /// Payload is not a Pot payload.
15    NotAPot,
16    /// Data was written with an incompatible version.
17    IncompatibleVersion,
18    /// A generic error occurred.
19    Message(String),
20    /// Extra data appeared at the end of the input.
21    TrailingBytes,
22    /// Expected more data but encountered the end of the input.
23    Eof,
24    /// A numerical value could not be handled without losing precision or truncation.
25    ImpreciseCastWouldLoseData,
26    /// An IO error occurred.
27    Io(io::Error),
28    /// A sequence of unknown size cannot be serialized.
29    SequenceSizeMustBeKnown,
30    /// String data contained invalid UTF-8 characters.
31    InvalidUtf8(String),
32    /// An unknown kind was encountered. Generally a sign that something else has been parsed incorrectly.
33    InvalidKind(u8),
34    /// Encountered an unexpected atom kind.
35    UnexpectedKind(Kind, Kind),
36    /// A requested symbol id was not found.
37    UnknownSymbol(u64),
38    /// An unsupported byte count for a numeric type was encountered.
39    UnsupportedByteCount(Kind, usize),
40    /// An atom header was incorrectly formatted.
41    InvalidAtomHeader,
42    /// The amount of data read exceeds the configured maximum number of bytes.
43    TooManyBytesRead,
44    /// An unknown [`Special`](crate::format::Special) was encountered.
45    UnknownSpecial(UnknownSpecial),
46}
47
48impl Display for Error {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        match self {
51            Error::NotAPot => f.write_str("not a pot: invalid header"),
52            Error::IncompatibleVersion => f.write_str("incompatible version"),
53            Error::Message(message) => f.write_str(message),
54            Error::TrailingBytes => f.write_str("extra data at end of input"),
55            Error::Eof => f.write_str("unexpected end of file"),
56            Error::ImpreciseCastWouldLoseData => f.write_str("numerical data cannot fit"),
57            Error::Io(io) => write!(f, "io error: {io}"),
58            Error::SequenceSizeMustBeKnown => {
59                f.write_str("serializing sequences of unknown size is unsupported")
60            }
61            Error::InvalidUtf8(err) => write!(f, "invalid utf8: {err}"),
62            Error::InvalidKind(kind) => write!(f, "invalid kind: {kind}"),
63            Error::UnexpectedKind(encountered, expected) => write!(
64                f,
65                "encountered atom kind {encountered:?}, expected {expected:?}"
66            ),
67            Error::UnknownSymbol(sym) => write!(f, "unknown symbol {sym}"),
68            Error::InvalidAtomHeader => f.write_str("an atom header was incorrectly formatted"),
69            Error::TooManyBytesRead => {
70                f.write_str("the deserialized value is larger than the allowed allocation limit")
71            }
72            Error::UnsupportedByteCount(kind, count) => {
73                write!(f, "unexpected {kind:?} byte count ({count})")
74            }
75            Error::UnknownSpecial(err) => Display::fmt(err, f),
76        }
77    }
78}
79
80impl std::error::Error for Error {}
81
82impl From<io::Error> for Error {
83    fn from(err: io::Error) -> Self {
84        Self::Io(err)
85    }
86}
87
88impl ser::Error for Error {
89    fn custom<T: Display>(msg: T) -> Self {
90        Self::Message(msg.to_string())
91    }
92}
93
94impl de::Error for Error {
95    fn custom<T: Display>(msg: T) -> Self {
96        Self::Message(msg.to_string())
97    }
98}
99
100impl From<Utf8Error> for Error {
101    fn from(err: Utf8Error) -> Self {
102        Self::InvalidUtf8(err.to_string())
103    }
104}
105
106impl From<FromUtf8Error> for Error {
107    fn from(err: FromUtf8Error) -> Self {
108        Self::InvalidUtf8(err.to_string())
109    }
110}
111
112impl From<UnknownSpecial> for Error {
113    fn from(err: UnknownSpecial) -> Self {
114        Self::UnknownSpecial(err)
115    }
116}