musli_json/
error.rs

1use core::fmt;
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::string::ToString;
7
8/// Error raised during json encoding.
9#[derive(Debug)]
10pub struct Error {
11    err: ErrorImpl,
12}
13
14impl fmt::Display for Error {
15    #[inline]
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        self.err.fmt(f)
18    }
19}
20
21#[derive(Debug)]
22enum ErrorImpl {
23    #[cfg(feature = "alloc")]
24    Message(Box<str>),
25    #[cfg(not(feature = "alloc"))]
26    Empty,
27}
28
29impl fmt::Display for ErrorImpl {
30    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31        match self {
32            #[cfg(feature = "alloc")]
33            ErrorImpl::Message(message) => message.fmt(f),
34            #[cfg(not(feature = "alloc"))]
35            ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"),
36        }
37    }
38}
39
40#[cfg(feature = "std")]
41impl std::error::Error for Error {}
42
43impl musli_utils::context::Error for Error {
44    #[inline]
45    fn custom<T>(error: T) -> Self
46    where
47        T: fmt::Display,
48    {
49        Self::message(error)
50    }
51
52    #[inline]
53    #[allow(unused_variables)]
54    fn message<T>(message: T) -> Self
55    where
56        T: fmt::Display,
57    {
58        Self {
59            #[cfg(feature = "alloc")]
60            err: ErrorImpl::Message(message.to_string().into()),
61            #[cfg(not(feature = "alloc"))]
62            err: ErrorImpl::Empty,
63        }
64    }
65}
66
67#[derive(Debug)]
68#[non_exhaustive]
69pub(crate) enum ErrorMessage {
70    ParseFloat(lexical::Error),
71}
72
73impl fmt::Display for ErrorMessage {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        match self {
76            ErrorMessage::ParseFloat(error) => {
77                write!(f, "Expected float, got {error}")
78            }
79        }
80    }
81}
82
83#[cfg(feature = "std")]
84impl std::error::Error for ErrorMessage {
85    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
86        match self {
87            ErrorMessage::ParseFloat(error) => Some(error),
88        }
89    }
90}
91
92#[derive(Debug)]
93#[non_exhaustive]
94pub(crate) enum IntegerError {
95    IntegerOverflow,
96    Decimal,
97    InvalidNumeric,
98}
99
100impl fmt::Display for IntegerError {
101    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102        match self {
103            IntegerError::IntegerOverflow => write!(f, "Arithmetic overflow"),
104            IntegerError::Decimal => write!(f, "Decimal number"),
105            IntegerError::InvalidNumeric => write!(f, "Invalid numeric"),
106        }
107    }
108}