tower_sesh/value/
error.rs

1// Adapted from https://github.com/serde-rs/json.
2
3use std::{error::Error as StdError, fmt};
4
5pub struct Error {
6    // TODO: Compare benchmarks when `err` is boxed.
7    err: ErrorImpl,
8}
9
10pub(super) enum ErrorImpl {
11    /// Catchall for a general error.
12    Message(Box<str>),
13
14    /// Map key is a non-finite float value.
15    FloatKeyMustBeFinite,
16
17    /// Float is a non-finite value.
18    FloatMustBeFinite,
19
20    /// Map key is not a string.
21    KeyMustBeAString,
22
23    /// Number is bigger than the maximum value of its type.
24    NumberOutOfRange,
25}
26
27impl From<ErrorImpl> for Error {
28    #[inline]
29    fn from(err: ErrorImpl) -> Self {
30        Error { err }
31    }
32}
33
34impl StdError for Error {
35    fn source(&self) -> Option<&(dyn StdError + 'static)> {
36        None
37    }
38}
39
40impl fmt::Display for ErrorImpl {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        use ErrorImpl::*;
43        match self {
44            Message(msg) => f.write_str(msg),
45            FloatKeyMustBeFinite => f.write_str("float key must be finite (got NaN or +/-inf)"),
46            FloatMustBeFinite => f.write_str("float must be finite (got NaN or +/-inf)"),
47            KeyMustBeAString => f.write_str("key must be a string"),
48            NumberOutOfRange => f.write_str("number out of range"),
49        }
50    }
51}
52
53impl fmt::Display for Error {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        fmt::Display::fmt(&self.err, f)
56    }
57}
58
59impl fmt::Debug for Error {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(f, "Error({:?})", self.err.to_string())
62    }
63}
64
65impl serde::de::Error for Error {
66    #[cold]
67    fn custom<T>(msg: T) -> Self
68    where
69        T: fmt::Display,
70    {
71        make_error(msg.to_string())
72    }
73}
74
75impl serde::ser::Error for Error {
76    #[cold]
77    fn custom<T>(msg: T) -> Self
78    where
79        T: std::fmt::Display,
80    {
81        make_error(msg.to_string())
82    }
83}
84
85fn make_error(msg: String) -> Error {
86    Error {
87        err: ErrorImpl::Message(msg.into_boxed_str()),
88    }
89}