1use alloc::string::String;
2use core::fmt;
3
4use facet_core::{ScalarType, Shape};
5use facet_path::Path;
6use facet_reflect::ReflectError;
7
8#[cfg(feature = "pretty-errors")]
9use facet_path::pretty::PathDiagnostic;
10
11#[derive(Debug)]
13pub enum SerializeError {
14 BufferTooSmall,
16 UnsupportedType(&'static str),
18 UnsupportedScalar {
20 scalar_type: ScalarType,
22 path: Path,
24 root_shape: &'static Shape,
26 },
27 UnknownScalar {
29 type_name: &'static str,
31 path: Path,
33 root_shape: &'static Shape,
35 },
36}
37
38pub use facet_path::{Path as ErrorPath, PathStep as ErrorPathStep};
40
41impl SerializeError {
42 pub fn format_simple(&self) -> String {
44 match self {
45 SerializeError::BufferTooSmall => String::from("Buffer too small for serialized data"),
46 SerializeError::UnsupportedType(ty) => {
47 alloc::format!("Unsupported type for postcard serialization: {ty}")
48 }
49 SerializeError::UnsupportedScalar {
50 scalar_type,
51 path,
52 root_shape,
53 } => {
54 let path_str = path.format_with_shape(root_shape);
55 alloc::format!(
56 "Unsupported scalar type {:?} at path: {}",
57 scalar_type,
58 path_str
59 )
60 }
61 SerializeError::UnknownScalar {
62 type_name,
63 path,
64 root_shape,
65 } => {
66 let path_str = path.format_with_shape(root_shape);
67 alloc::format!("Unknown scalar type '{}' at path: {}", type_name, path_str)
68 }
69 }
70 }
71
72 #[cfg(feature = "pretty-errors")]
74 pub fn format_pretty(&self) -> String {
75 match self {
76 SerializeError::BufferTooSmall => String::from("Buffer too small for serialized data"),
77 SerializeError::UnsupportedType(ty) => {
78 alloc::format!("Unsupported type for postcard serialization: {ty}")
79 }
80 SerializeError::UnsupportedScalar {
81 scalar_type,
82 path,
83 root_shape,
84 } => {
85 let message = alloc::format!("Unsupported scalar type: {:?}", scalar_type);
86 path.format_pretty(root_shape, message, None)
87 }
88 SerializeError::UnknownScalar {
89 type_name,
90 path,
91 root_shape,
92 } => {
93 let message = alloc::format!("Unknown scalar type: {}", type_name);
94 path.format_pretty(root_shape, message, None)
95 }
96 }
97 }
98
99 #[cfg(feature = "pretty-errors")]
101 pub fn format_pretty_no_color(&self) -> String {
102 match self {
103 SerializeError::BufferTooSmall => String::from("Buffer too small for serialized data"),
104 SerializeError::UnsupportedType(ty) => {
105 alloc::format!("Unsupported type for postcard serialization: {ty}")
106 }
107 SerializeError::UnsupportedScalar {
108 scalar_type,
109 path,
110 root_shape,
111 } => {
112 let message = alloc::format!("Unsupported scalar type: {:?}", scalar_type);
113 path.format_pretty_no_color(root_shape, message, None)
114 }
115 SerializeError::UnknownScalar {
116 type_name,
117 path,
118 root_shape,
119 } => {
120 let message = alloc::format!("Unknown scalar type: {}", type_name);
121 path.format_pretty_no_color(root_shape, message, None)
122 }
123 }
124 }
125}
126
127impl fmt::Display for SerializeError {
128 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129 #[cfg(feature = "pretty-errors")]
130 {
131 write!(f, "{}", self.format_pretty())
132 }
133 #[cfg(not(feature = "pretty-errors"))]
134 {
135 write!(f, "{}", self.format_simple())
136 }
137 }
138}
139
140#[cfg(feature = "std")]
141impl std::error::Error for SerializeError {}
142
143#[cfg(feature = "pretty-errors")]
144impl miette::Diagnostic for SerializeError {
145 fn source_code(&self) -> Option<&dyn miette::SourceCode> {
146 None
148 }
149
150 fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn miette::Diagnostic> + 'a>> {
151 None
153 }
154
155 fn diagnostic_source(&self) -> Option<&dyn miette::Diagnostic> {
156 None
157 }
158}
159
160impl SerializeError {
161 #[cfg(feature = "pretty-errors")]
163 pub fn to_diagnostic(&self) -> Option<PathDiagnostic> {
164 match self {
165 SerializeError::UnsupportedScalar {
166 scalar_type,
167 path,
168 root_shape,
169 } => {
170 let message = alloc::format!("Unsupported scalar type: {:?}", scalar_type);
171 Some(path.to_diagnostic(root_shape, message, None))
172 }
173 SerializeError::UnknownScalar {
174 type_name,
175 path,
176 root_shape,
177 } => {
178 let message = alloc::format!("Unsupported scalar type: {}", type_name);
179 Some(path.to_diagnostic(root_shape, message, None))
180 }
181 _ => None,
182 }
183 }
184}
185
186#[derive(Debug)]
188pub enum DeserializeError {
189 UnexpectedEnd,
191 InvalidData,
193 IntegerOverflow,
195 UnknownField,
197 MissingField(&'static str),
199 UnsupportedShape,
201 UnsupportedType(&'static str),
203 InvalidVariant,
205 InvalidBool,
207 InvalidUtf8,
209 ReflectError(ReflectError),
211 LengthMismatch,
213}
214
215impl From<ReflectError> for DeserializeError {
216 fn from(err: ReflectError) -> Self {
217 Self::ReflectError(err)
218 }
219}
220
221impl fmt::Display for DeserializeError {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 match self {
224 DeserializeError::UnexpectedEnd => write!(f, "Unexpected end of input"),
225 DeserializeError::InvalidData => write!(f, "Invalid postcard data"),
226 DeserializeError::IntegerOverflow => {
227 write!(f, "Integer value too large for target type")
228 }
229 DeserializeError::UnknownField => write!(f, "Unknown field encountered"),
230 DeserializeError::MissingField(field) => {
231 write!(f, "Missing required field: {field}")
232 }
233 DeserializeError::UnsupportedShape => {
234 write!(f, "Unsupported shape for deserialization")
235 }
236 DeserializeError::UnsupportedType(ty) => {
237 write!(f, "Unsupported type for deserialization: {ty}")
238 }
239 DeserializeError::InvalidVariant => write!(f, "Invalid enum variant index"),
240 DeserializeError::InvalidBool => write!(f, "Invalid boolean value (expected 0 or 1)"),
241 DeserializeError::InvalidUtf8 => write!(f, "Invalid UTF-8 in string data"),
242 DeserializeError::ReflectError(err) => write!(f, "Reflection error: {err}"),
243 DeserializeError::LengthMismatch => write!(f, "Sequence length mismatch"),
244 }
245 }
246}
247
248#[cfg(feature = "std")]
249impl std::error::Error for DeserializeError {}