serde_saphyr/
ser_error.rs

1use std::{fmt, io};
2
3/// Error type used by the YAML serializer.
4///
5/// This type is re-exported as `serde_saphyr::ser::Error` and is returned by
6/// the public serialization APIs (for example `serde_saphyr::to_string`).
7///
8/// It implements `serde::ser::Error`, which allows user `Serialize` impls and
9/// Serde derives to report failures via `S::Error::custom(...)`. Such
10/// free‑form messages are stored in the `Message` variant.
11///
12/// Other variants wrap concrete underlying failures that can occur while
13/// serializing:
14/// - `Format` wraps a `std::fmt::Error` produced when writing to a
15///   `fmt::Write` target.
16/// - `IO` wraps a `std::io::Error` produced when writing to an `io::Write`
17///   target.
18/// - `Unexpected` is used internally for invariant violations (e.g., around
19///   anchors). It should not normally surface; if it does, please file a bug.
20#[derive(Debug)]
21pub enum Error {
22    /// Free-form error.
23    Message { msg: String },
24    /// Wrapper for formatting errors.
25    Format { error: fmt::Error },
26    /// Wrapper for I/O errors.
27    IO { error: io::Error },
28    /// This is used with anchors and should normally not surface, please report bug if it does.
29    Unexpected { msg: String }
30}
31
32impl serde::ser::Error for Error {
33    fn custom<T: fmt::Display>(msg: T) -> Self {
34        Error::Message {
35            msg: msg.to_string(),
36        }
37    }
38}
39
40impl From<fmt::Error> for Error {
41    fn from(error: fmt::Error) -> Self {
42        Error::Format { error }
43    }
44}
45
46impl From<io::Error> for Error {
47    fn from(error: io::Error) -> Self {
48        Error::IO { error }
49    }
50}
51
52impl From<String> for Error
53{
54    fn from(message: String) -> Self {
55        Error::Message {
56            msg: message,
57        }
58    }
59}
60
61impl From<&String> for Error
62{
63    fn from(message: &String) -> Self {
64        Error::Message {
65            msg: message.clone(),
66        }
67    }
68}
69
70impl From<&str> for Error
71{
72    fn from(message: &str) -> Self {
73        Error::Message {
74            msg: message.to_string(),
75        }
76    }
77}
78
79impl Error {
80    pub(crate) fn unexpected(message: &str) -> Self {
81        Error::Unexpected {
82            msg: message.to_string(),
83        }
84    }
85}
86
87impl fmt::Display for Error {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        match self {
90            Error::Message { msg } => f.write_str(msg),
91            Error::Format { error } => write!(f, "formatting error: {error}"),
92            Error::IO { error } => write!(f, "I/O error: {error}"),
93            Error::Unexpected { msg } => write!(f, "unexpected internal error: {msg}"),
94        }
95    }
96}
97
98impl std::error::Error for Error {
99    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
100        match self {
101            Error::Message { .. } => None,
102            Error::Unexpected { .. } => None,
103            Error::Format { error } => Some(error),
104            Error::IO { error } => Some(error),
105        }
106    }
107}