1use facet_core::{Characteristic, EnumType, FieldError, Shape, TryFromError};
2
3#[allow(missing_docs)]
5#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
6#[non_exhaustive]
7pub enum TrackerKind {
8 Scalar,
9 Array,
10 Struct,
11 SmartPointer,
12 SmartPointerSlice,
13 Enum,
14 List,
15 Map,
16 Set,
17 Option,
18 Result,
19 DynamicValue,
20}
21
22#[derive(Clone)]
24pub enum ReflectError {
25 NoSuchVariant {
27 enum_type: EnumType,
29 },
30
31 WrongShape {
34 expected: &'static Shape,
36 actual: &'static Shape,
38 },
39
40 WasNotA {
42 expected: &'static str,
44
45 actual: &'static Shape,
47 },
48
49 UninitializedField {
51 shape: &'static Shape,
53 field_name: &'static str,
55 },
56
57 UninitializedEnumField {
59 shape: &'static Shape,
61 field_name: &'static str,
63 variant_name: &'static str,
65 },
66
67 UninitializedValue {
69 shape: &'static Shape,
71 },
72
73 InvariantViolation {
75 invariant: &'static str,
77 },
78
79 MissingCharacteristic {
81 shape: &'static Shape,
83 characteristic: Characteristic,
85 },
86
87 OperationFailed {
89 shape: &'static Shape,
91 operation: &'static str,
93 },
94
95 FieldError {
97 shape: &'static Shape,
99 field_error: FieldError,
101 },
102
103 NotPod {
109 shape: &'static Shape,
111 },
112
113 MissingPushPointee {
116 shape: &'static Shape,
118 },
119
120 Unknown,
122
123 TryFromError {
125 src_shape: &'static Shape,
127
128 dst_shape: &'static Shape,
130
131 inner: TryFromError,
133 },
134
135 DefaultAttrButNoDefaultImpl {
137 shape: &'static Shape,
139 },
140
141 Unsized {
143 shape: &'static Shape,
145 operation: &'static str,
147 },
148
149 ArrayNotFullyInitialized {
151 shape: &'static Shape,
153 pushed_count: usize,
155 expected_size: usize,
157 },
158
159 ArrayIndexOutOfBounds {
161 shape: &'static Shape,
163 index: usize,
165 size: usize,
167 },
168
169 InvalidOperation {
171 operation: &'static str,
173 reason: &'static str,
175 },
176
177 UnexpectedTracker {
179 message: &'static str,
182
183 current_tracker: TrackerKind,
185 },
186
187 NoActiveFrame,
189
190 #[cfg(feature = "alloc")]
191 CustomDeserializationError {
193 message: alloc::string::String,
195 src_shape: &'static Shape,
197 dst_shape: &'static Shape,
199 },
200
201 #[cfg(feature = "alloc")]
202 UserInvariantFailed {
204 message: alloc::string::String,
206 shape: &'static Shape,
208 },
209
210 #[cfg(feature = "alloc")]
211 CustomSerializationError {
213 message: alloc::string::String,
215 src_shape: &'static Shape,
217 dst_shape: &'static Shape,
219 },
220}
221
222impl core::fmt::Display for ReflectError {
223 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
224 match self {
225 ReflectError::NoSuchVariant { enum_type } => {
226 write!(f, "No such variant in enum. Known variants: ")?;
227 for v in enum_type.variants {
228 write!(f, ", {}", v.name)?;
229 }
230 write!(f, ", that's it.")
231 }
232 ReflectError::WrongShape { expected, actual } => {
233 write!(f, "Wrong shape: expected {expected}, but got {actual}")
234 }
235 ReflectError::WasNotA { expected, actual } => {
236 write!(f, "Wrong shape: expected {expected}, but got {actual}")
237 }
238 ReflectError::UninitializedField { shape, field_name } => {
239 write!(
240 f,
241 "Field '{shape}::{field_name}' was not initialized. \
242 If you need to leave fields partially initialized and come back later, \
243 use deferred mode (begin_deferred/finish_deferred)"
244 )
245 }
246 ReflectError::UninitializedEnumField {
247 shape,
248 field_name,
249 variant_name,
250 } => {
251 write!(
252 f,
253 "Field '{shape}::{field_name}' in variant '{variant_name}' was not initialized. \
254 If you need to leave fields partially initialized and come back later, \
255 use deferred mode (begin_deferred/finish_deferred)"
256 )
257 }
258 ReflectError::UninitializedValue { shape } => {
259 write!(
260 f,
261 "Value '{shape}' was not initialized. \
262 If you need to leave values partially initialized and come back later, \
263 use deferred mode (begin_deferred/finish_deferred)"
264 )
265 }
266 ReflectError::InvariantViolation { invariant } => {
267 write!(f, "Invariant violation: {invariant}")
268 }
269 ReflectError::MissingCharacteristic {
270 shape,
271 characteristic,
272 } => write!(
273 f,
274 "{shape} does not implement characteristic {characteristic:?}",
275 ),
276 ReflectError::OperationFailed { shape, operation } => {
277 write!(f, "Operation failed on shape {shape}: {operation}")
278 }
279 ReflectError::FieldError { shape, field_error } => {
280 write!(f, "Field error for shape {shape}: {field_error}")
281 }
282 ReflectError::NotPod { shape } => {
283 write!(
284 f,
285 "Cannot mutate fields of '{shape}' - it is not POD (Plain Old Data). \
286 Add #[facet(pod)] to the struct to enable field mutation. \
287 (Wholesale replacement via Poke::set() is always allowed.)"
288 )
289 }
290 ReflectError::MissingPushPointee { shape } => {
291 write!(
292 f,
293 "Tried to access a field on smart pointer '{shape}', but you need to call .begin_smart_ptr() first to work with the value it points to (and pop it with .pop() later)"
294 )
295 }
296 ReflectError::Unknown => write!(f, "Unknown error"),
297 ReflectError::TryFromError {
298 src_shape,
299 dst_shape,
300 inner,
301 } => {
302 write!(
303 f,
304 "While trying to put {src_shape} into a {dst_shape}: {inner}"
305 )
306 }
307 ReflectError::DefaultAttrButNoDefaultImpl { shape } => write!(
308 f,
309 "Shape '{shape}' has a `default` attribute but no default implementation"
310 ),
311 ReflectError::Unsized { shape, operation } => write!(
312 f,
313 "Shape '{shape}' is unsized, can't perform operation {operation}"
314 ),
315 ReflectError::ArrayNotFullyInitialized {
316 shape,
317 pushed_count,
318 expected_size,
319 } => {
320 write!(
321 f,
322 "Array '{shape}' not fully initialized: expected {expected_size} elements, but got {pushed_count}"
323 )
324 }
325 ReflectError::ArrayIndexOutOfBounds { shape, index, size } => {
326 write!(
327 f,
328 "Array index {index} out of bounds for '{shape}' (array length is {size})"
329 )
330 }
331 ReflectError::InvalidOperation { operation, reason } => {
332 write!(f, "Invalid operation '{operation}': {reason}")
333 }
334 ReflectError::UnexpectedTracker {
335 message,
336 current_tracker,
337 } => {
338 write!(f, "{message}: current tracker is {current_tracker:?}")
339 }
340 ReflectError::NoActiveFrame => {
341 write!(f, "No active frame in Partial")
342 }
343 #[cfg(feature = "alloc")]
344 ReflectError::CustomDeserializationError {
345 message,
346 src_shape,
347 dst_shape,
348 } => {
349 write!(
350 f,
351 "Custom deserialization of shape '{src_shape}' into '{dst_shape}' failed: {message}"
352 )
353 }
354 #[cfg(feature = "alloc")]
355 ReflectError::CustomSerializationError {
356 message,
357 src_shape,
358 dst_shape,
359 } => {
360 write!(
361 f,
362 "Custom serialization of shape '{src_shape}' into '{dst_shape}' failed: {message}"
363 )
364 }
365 #[cfg(feature = "alloc")]
366 ReflectError::UserInvariantFailed { message, shape } => {
367 write!(f, "Invariant check failed for '{shape}': {message}")
368 }
369 }
370 }
371}
372
373impl core::fmt::Debug for ReflectError {
374 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
375 write!(f, "ReflectError({self})")
377 }
378}
379
380impl core::error::Error for ReflectError {}