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
100impl fmt::Display for SerializeError {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 #[cfg(feature = "pretty-errors")]
103 {
104 write!(f, "{}", self.format_pretty())
105 }
106 #[cfg(not(feature = "pretty-errors"))]
107 {
108 write!(f, "{}", self.format_simple())
109 }
110 }
111}
112
113#[cfg(feature = "std")]
114impl std::error::Error for SerializeError {}
115
116#[cfg(feature = "pretty-errors")]
117impl miette::Diagnostic for SerializeError {
118 fn source_code(&self) -> Option<&dyn miette::SourceCode> {
119 None
121 }
122
123 fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn miette::Diagnostic> + 'a>> {
124 None
126 }
127
128 fn diagnostic_source(&self) -> Option<&dyn miette::Diagnostic> {
129 None
130 }
131}
132
133impl SerializeError {
134 #[cfg(feature = "pretty-errors")]
136 pub fn to_diagnostic(&self) -> Option<PathDiagnostic> {
137 match self {
138 SerializeError::UnsupportedScalar {
139 scalar_type,
140 path,
141 root_shape,
142 } => {
143 let message = alloc::format!("Unsupported scalar type: {:?}", scalar_type);
144 Some(path.to_diagnostic(root_shape, message, None))
145 }
146 SerializeError::UnknownScalar {
147 type_name,
148 path,
149 root_shape,
150 } => {
151 let message = alloc::format!("Unsupported scalar type: {}", type_name);
152 Some(path.to_diagnostic(root_shape, message, None))
153 }
154 _ => None,
155 }
156 }
157}
158
159#[derive(Debug)]
161pub enum DeserializeError {
162 UnexpectedEnd,
164 InvalidData,
166 IntegerOverflow,
168 UnknownField,
170 MissingField(&'static str),
172 UnsupportedShape,
174 UnsupportedType(&'static str),
176 InvalidVariant,
178 InvalidBool,
180 InvalidUtf8,
182 ReflectError(ReflectError),
184 LengthMismatch,
186}
187
188impl From<ReflectError> for DeserializeError {
189 fn from(err: ReflectError) -> Self {
190 Self::ReflectError(err)
191 }
192}
193
194impl fmt::Display for DeserializeError {
195 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196 match self {
197 DeserializeError::UnexpectedEnd => write!(f, "Unexpected end of input"),
198 DeserializeError::InvalidData => write!(f, "Invalid postcard data"),
199 DeserializeError::IntegerOverflow => {
200 write!(f, "Integer value too large for target type")
201 }
202 DeserializeError::UnknownField => write!(f, "Unknown field encountered"),
203 DeserializeError::MissingField(field) => {
204 write!(f, "Missing required field: {field}")
205 }
206 DeserializeError::UnsupportedShape => {
207 write!(f, "Unsupported shape for deserialization")
208 }
209 DeserializeError::UnsupportedType(ty) => {
210 write!(f, "Unsupported type for deserialization: {ty}")
211 }
212 DeserializeError::InvalidVariant => write!(f, "Invalid enum variant index"),
213 DeserializeError::InvalidBool => write!(f, "Invalid boolean value (expected 0 or 1)"),
214 DeserializeError::InvalidUtf8 => write!(f, "Invalid UTF-8 in string data"),
215 DeserializeError::ReflectError(err) => write!(f, "Reflection error: {err}"),
216 DeserializeError::LengthMismatch => write!(f, "Sequence length mismatch"),
217 }
218 }
219}
220
221#[cfg(feature = "std")]
222impl std::error::Error for DeserializeError {}