1use core::result;
2use std::error::Error as StdError;
3use std::fmt;
4use std::io;
5
6use num_bigint::BigInt;
7use serde::de;
8use serde::ser;
9
10#[derive(Debug)]
11pub enum Unexpected {
12 Bool(bool),
13 Integer(BigInt),
14 Float(f64),
15 Str(String),
16 Unit,
17 Array,
18 Map,
19}
20
21impl fmt::Display for Unexpected {
22 fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
23 match *self {
24 Unexpected::Bool(b) => write!(f, "boolean `{}`", b),
25 Unexpected::Integer(ref i) => write!(f, "integer `{}`", i),
26 Unexpected::Float(v) => write!(f, "floating point `{}`", v),
27 Unexpected::Str(ref s) => write!(f, "string {:?}", s),
28 Unexpected::Unit => write!(f, "unit value"),
29 Unexpected::Array => write!(f, "array"),
30 Unexpected::Map => write!(f, "map"),
31 }
32 }
33}
34
35pub struct Error {
36 inner: Box<ErrorImpl>,
37}
38
39pub type Result<T, E = Error> = result::Result<T, E>;
40
41impl From<io::Error> for Error {
42 fn from(source: io::Error) -> Self {
43 Error {
44 inner: Box::new(ErrorImpl::Io(source)),
45 }
46 }
47}
48
49impl From<std::convert::Infallible> for Error {
50 fn from(_: std::convert::Infallible) -> Self {
51 unreachable!()
52 }
53}
54
55impl Error {
56 #[doc(hidden)]
57 #[cold]
58 pub(crate) fn io(source: io::Error) -> Self {
59 Error {
60 inner: Box::new(ErrorImpl::Io(source)),
61 }
62 }
63
64 #[doc(hidden)]
65 #[cold]
66 pub(crate) fn too_large<T: Into<BigInt>>(index: T) -> Self {
67 Error {
68 inner: Box::new(ErrorImpl::Range(index.into())),
69 }
70 }
71
72 #[doc(hidden)]
73 #[cold]
74 pub(crate) fn invalid_type(unexpected: Unexpected, expected: &'static str) -> Self {
75 Error {
76 inner: Box::new(ErrorImpl::Type {
77 unexpected,
78 expected,
79 }),
80 }
81 }
82
83 #[doc(hidden)]
84 #[cold]
85 pub(crate) fn path_parse<R: pest::RuleType + Send + Sync + 'static>(
86 source: pest::error::Error<R>,
87 path: &str,
88 ) -> Self {
89 Error {
90 inner: Box::new(ErrorImpl::PathParse {
91 path: Box::from(path),
92 source: Box::new(source),
93 }),
94 }
95 }
96
97 #[doc(hidden)]
98 #[cold]
99 pub(crate) fn format_parse<E>(origin: &str, source: E) -> Self
100 where
101 E: StdError + Sync + Send + 'static,
102 {
103 Error {
104 inner: Box::new(ErrorImpl::FormatParse {
105 origin: origin.into(),
106 source: Box::new(source),
107 }),
108 }
109 }
110
111 #[doc(hidden)]
112 #[cold]
113 pub(crate) fn serde<T: AsRef<str>>(message: T) -> Self {
114 Error {
115 inner: Box::new(ErrorImpl::Serde(message.as_ref().into())),
116 }
117 }
118}
119
120impl fmt::Display for Error {
121 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
122 fmt::Display::fmt(&*self.inner, f)
123 }
124}
125
126impl fmt::Debug for Error {
127 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
128 write!(f, "{}", *self)
129 }
130}
131
132impl StdError for Error {
133 fn source(&self) -> Option<&(dyn StdError + 'static)> {
134 match *self.inner {
135 ErrorImpl::PathParse { ref source, .. } => Some(source.as_ref()),
136
137 ErrorImpl::FormatParse { ref source, .. } => Some(source.as_ref()),
138
139 _ => None,
140 }
141 }
142}
143
144impl de::Error for Error {
145 fn custom<T: fmt::Display>(msg: T) -> Self {
146 Error {
147 inner: Box::new(ErrorImpl::Serde(msg.to_string().into())),
148 }
149 }
150}
151
152impl ser::Error for Error {
153 fn custom<T: fmt::Display>(msg: T) -> Self {
154 Error {
155 inner: Box::new(ErrorImpl::Serde(msg.to_string().into())),
156 }
157 }
158}
159
160enum ErrorImpl {
163 PathParse {
165 path: Box<str>,
166 source: Box<dyn StdError + Send + Sync>,
167 },
168
169 Io(io::Error),
171
172 Type {
174 unexpected: Unexpected,
176
177 expected: &'static str,
179 },
180
181 FormatParse {
183 origin: Box<str>,
184 source: Box<dyn StdError + Send + Sync>,
185 },
186
187 Serde(Box<str>),
189
190 Range(BigInt),
192}
193
194impl fmt::Display for ErrorImpl {
195 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
196 match *self {
197 ErrorImpl::PathParse {
198 ref path,
199 ref source,
200 } => write!(f, "{}\n for {}", source, path),
201
202 ErrorImpl::Range(ref i) => write!(f, "invalid range {}", i),
203
204 ErrorImpl::Type {
205 ref unexpected,
206 expected,
207 } => {
208 write!(f, "invalid type: {}, expected {}", unexpected, expected)?;
209 Ok(())
210 }
211
212 ErrorImpl::Io(ref err) => write!(f, "{}", err),
213
214 ErrorImpl::Serde(ref s) => write!(f, "{}", s),
215
216 ErrorImpl::FormatParse {
217 ref source,
218 ref origin,
219 } => {
220 write!(f, "{}\n in {}", source, origin)?;
221 Ok(())
222 }
223 }
224 }
225}