musli_value/
error.rs

1use core::fmt;
2
3#[cfg(feature = "alloc")]
4use alloc::boxed::Box;
5#[cfg(feature = "alloc")]
6use alloc::string::ToString;
7
8use crate::type_hint::{NumberHint, TypeHint};
9
10/// An error raised when encoding or decoding [`Value`][crate::Value].
11#[derive(Debug)]
12pub struct Error {
13    err: ErrorImpl,
14}
15
16impl fmt::Display for Error {
17    #[inline]
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        self.err.fmt(f)
20    }
21}
22
23#[allow(missing_docs)]
24#[derive(Debug)]
25#[non_exhaustive]
26enum ErrorImpl {
27    #[cfg(feature = "alloc")]
28    Message(Box<str>),
29    #[cfg(not(feature = "alloc"))]
30    Empty,
31}
32
33impl fmt::Display for ErrorImpl {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        match self {
36            #[cfg(feature = "alloc")]
37            ErrorImpl::Message(message) => message.fmt(f),
38            #[cfg(not(feature = "alloc"))]
39            ErrorImpl::Empty => write!(f, "Message error (see diagnostics)"),
40        }
41    }
42}
43
44#[cfg(feature = "std")]
45impl std::error::Error for Error {}
46
47impl musli_utils::context::Error for Error {
48    #[inline]
49    fn custom<T>(error: T) -> Self
50    where
51        T: fmt::Display,
52    {
53        Self::message(error)
54    }
55
56    #[inline]
57    #[allow(unused_variables)]
58    fn message<T>(message: T) -> Self
59    where
60        T: fmt::Display,
61    {
62        Self {
63            #[cfg(feature = "alloc")]
64            err: ErrorImpl::Message(message.to_string().into()),
65            #[cfg(not(feature = "alloc"))]
66            err: ErrorImpl::Empty,
67        }
68    }
69}
70
71/// Errors specifically produced by value decoding.
72#[derive(Debug)]
73#[non_exhaustive]
74#[allow(missing_docs)]
75pub(crate) enum ErrorMessage {
76    #[cfg(feature = "alloc")]
77    ArrayOutOfBounds,
78    ExpectedPackValue,
79    ExpectedUnit(TypeHint),
80    ExpectedBool(TypeHint),
81    ExpectedChar(TypeHint),
82    ExpectedNumber(NumberHint, TypeHint),
83    ExpectedMapValue,
84    #[cfg(feature = "alloc")]
85    ExpectedBytes(TypeHint),
86    #[cfg(feature = "alloc")]
87    ExpectedString(TypeHint),
88    #[cfg(feature = "alloc")]
89    ExpectedStringAsNumber,
90    #[cfg(feature = "alloc")]
91    ExpectedOption(TypeHint),
92    #[cfg(feature = "alloc")]
93    ExpectedSequence(TypeHint),
94    #[cfg(feature = "alloc")]
95    ExpectedPack(TypeHint),
96    #[cfg(feature = "alloc")]
97    ExpectedMap(TypeHint),
98    #[cfg(feature = "alloc")]
99    ExpectedVariant(TypeHint),
100}
101
102impl fmt::Display for ErrorMessage {
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        match self {
105            #[cfg(feature = "alloc")]
106            ErrorMessage::ArrayOutOfBounds => {
107                write!(
108                    f,
109                    "Value buffer tried to decode array that is out-of-bounds"
110                )
111            }
112            ErrorMessage::ExpectedPackValue => write!(f, "Value buffer expected pack value"),
113            ErrorMessage::ExpectedUnit(hint) => {
114                write!(f, "Value buffer expected unit, but found {hint}")
115            }
116            ErrorMessage::ExpectedBool(hint) => {
117                write!(f, "Value buffer expected boolean, but found {hint}")
118            }
119            ErrorMessage::ExpectedChar(hint) => {
120                write!(f, "Value buffer expected character, but found {hint}")
121            }
122            ErrorMessage::ExpectedNumber(number, hint) => {
123                write!(f, "Value buffer expected {number}, but found {hint}")
124            }
125            ErrorMessage::ExpectedMapValue => write!(f, "Value buffer expected map value"),
126            #[cfg(feature = "alloc")]
127            ErrorMessage::ExpectedBytes(hint) => {
128                write!(f, "Value buffer expected bytes, but found {hint}")
129            }
130            #[cfg(feature = "alloc")]
131            ErrorMessage::ExpectedString(hint) => {
132                write!(f, "Value buffer expected string, but found {hint}")
133            }
134            #[cfg(feature = "alloc")]
135            ErrorMessage::ExpectedStringAsNumber => {
136                write!(f, "Value buffer expected string containing number")
137            }
138            #[cfg(feature = "alloc")]
139            ErrorMessage::ExpectedOption(hint) => {
140                write!(f, "Value buffer expected option, but found {hint}")
141            }
142            #[cfg(feature = "alloc")]
143            ErrorMessage::ExpectedSequence(hint) => {
144                write!(f, "Value buffer expected sequence, but found {hint}")
145            }
146            #[cfg(feature = "alloc")]
147            ErrorMessage::ExpectedPack(hint) => {
148                write!(f, "Value buffer expected pack of bytes, but found {hint}")
149            }
150            #[cfg(feature = "alloc")]
151            ErrorMessage::ExpectedMap(hint) => {
152                write!(f, "Value buffer expected map, but found {hint}")
153            }
154            #[cfg(feature = "alloc")]
155            ErrorMessage::ExpectedVariant(hint) => {
156                write!(f, "Value buffer expected struct, but found {hint}")
157            }
158        }
159    }
160}