mason_rs/serde/
error.rs

1//! When serializing or deserializing MASON goes wrong.
2
3use std::{
4    fmt::{self, Debug, Display},
5    io,
6};
7
8use serde::{de, ser};
9
10/// Alias for a `Result` with the error type `mason_rs::serde::error::Error`.
11pub type Result<T> = std::result::Result<T, Error>;
12
13/// This type represents all possible errors that can occur when serializing or
14/// deserializing MASON data.
15pub struct Error {
16    /// This `Box` allows us to keep the size of `Error` as small as possible.
17    inner: Box<InnerError>,
18}
19
20impl Debug for Error {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        self.inner.fmt(f)
23    }
24}
25
26#[derive(Debug)]
27enum InnerError {
28    // Created by data structures through the `ser::Error` and `de::Error` traits.
29    Message(String),
30    Io(io::Error),
31    Eof,
32    Fmt,
33}
34
35impl Error {
36    #[inline]
37    pub fn eof() -> Self {
38        Self {
39            inner: Box::new(InnerError::Eof),
40        }
41    }
42
43    #[inline]
44    pub fn fmt() -> Self {
45        Self {
46            inner: Box::new(InnerError::Fmt),
47        }
48    }
49}
50
51impl From<fmt::Error> for Error {
52    fn from(_value: fmt::Error) -> Self {
53        Self {
54            inner: Box::new(InnerError::Fmt),
55        }
56    }
57}
58
59impl From<io::Error> for Error {
60    fn from(value: io::Error) -> Self {
61        if matches!(value.kind(), io::ErrorKind::UnexpectedEof) {
62            Self {
63                inner: Box::new(InnerError::Eof),
64            }
65        } else {
66            Self {
67                inner: Box::new(InnerError::Io(value)),
68            }
69        }
70    }
71}
72
73impl ser::Error for Error {
74    fn custom<T: Display>(msg: T) -> Self {
75        Self {
76            inner: Box::new(InnerError::Message(msg.to_string())),
77        }
78    }
79}
80
81impl de::Error for Error {
82    fn custom<T: Display>(msg: T) -> Self {
83        Self {
84            inner: Box::new(InnerError::Message(msg.to_string())),
85        }
86    }
87}
88
89impl Display for Error {
90    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
91        match self.inner.as_ref() {
92            InnerError::Message(msg) => formatter.write_str(msg),
93            InnerError::Io(error) => write!(formatter, "{error}"),
94            InnerError::Eof => formatter.write_str("unexpected end of input"),
95            InnerError::Fmt => formatter.write_str("failed to write to writer"),
96        }
97    }
98}
99
100impl std::error::Error for Error {}