use core::fmt;
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Debug)]
pub enum Error {
Message(Box<str>),
Eof,
ExpectedColon,
ExpectedOpenParen,
ExpectedCloseParen,
ExpectedOpenBrace,
ExpectedCloseBrace,
ExpectedOpenBracket,
ExpectedCloseBracket,
ExpectedOpenAngle,
ExpectedCloseAngle,
ExpectedComma,
ExpectedValue,
TrailingCharacters,
TrailingBytes,
InvalidEscape(char),
InvalidNumber,
IntegerOutOfRange,
InvalidBool,
InvalidTag,
InvalidUtf8,
VarintOverflow,
SequenceTooLong,
AllocationFailed,
UnclosedString,
UnclosedComment,
UnclosedParen,
UnclosedBracket,
FieldCountMismatch { expected: u32, got: u32 },
InvalidUnicodeEscape,
DepthLimitExceeded,
}
impl Error {
#[cold]
#[inline(never)]
pub(crate) fn msg(s: impl Into<Box<str>>) -> Self {
Error::Message(s.into())
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Message(msg) => write!(f, "{}", msg),
Error::Eof => write!(f, "unexpected end of input"),
Error::ExpectedColon => write!(f, "expected ':'"),
Error::ExpectedOpenParen => write!(f, "expected '('"),
Error::ExpectedCloseParen => write!(f, "expected ')'"),
Error::ExpectedOpenBrace => write!(f, "expected '{{'"),
Error::ExpectedCloseBrace => write!(f, "expected '}}'"),
Error::ExpectedOpenBracket => write!(f, "expected '['"),
Error::ExpectedCloseBracket => write!(f, "expected ']'"),
Error::ExpectedOpenAngle => write!(f, "expected '<'"),
Error::ExpectedCloseAngle => write!(f, "expected '>'"),
Error::ExpectedComma => write!(f, "expected ','"),
Error::ExpectedValue => write!(f, "expected value"),
Error::TrailingCharacters => write!(f, "trailing characters"),
Error::TrailingBytes => write!(f, "trailing bytes"),
Error::InvalidEscape(c) => write!(f, "invalid escape: \\{}", c),
Error::InvalidNumber => write!(f, "invalid number"),
Error::IntegerOutOfRange => write!(f, "integer out of range for target type"),
Error::InvalidBool => write!(f, "invalid bool"),
Error::InvalidTag => write!(f, "invalid binary tag"),
Error::InvalidUtf8 => write!(f, "invalid utf-8"),
Error::VarintOverflow => write!(f, "varint overflow"),
Error::SequenceTooLong => write!(f, "sequence exceeds decode limit"),
Error::AllocationFailed => write!(f, "allocation failed"),
Error::UnclosedString => write!(f, "unclosed string"),
Error::UnclosedComment => write!(f, "unclosed comment"),
Error::UnclosedParen => write!(f, "unclosed parenthesis"),
Error::UnclosedBracket => write!(f, "unclosed bracket"),
Error::FieldCountMismatch { expected, got } => {
write!(
f,
"field count mismatch: expected {}, got {}",
expected, got
)
}
Error::InvalidUnicodeEscape => write!(f, "invalid unicode escape"),
Error::DepthLimitExceeded => write!(f, "input nesting exceeds the depth limit"),
}
}
}
impl std::error::Error for Error {}
#[cfg(test)]
mod tests {
use super::Error;
#[test]
fn error_stays_small() {
assert!(
core::mem::size_of::<Error>() <= 24,
"Error grew to {} bytes",
core::mem::size_of::<Error>()
);
assert!(core::mem::size_of::<super::Result<i64>>() <= 32);
}
}