facet_reflect/
error.rs

1use facet_core::{Characteristic, EnumType, FieldError, Shape, TryFromError};
2use owo_colors::OwoColorize;
3
4/// Errors that can occur when reflecting on types.
5#[derive(Debug, PartialEq, Clone)]
6#[non_exhaustive]
7pub enum ReflectError {
8    /// Tried to set an enum to a variant that does not exist
9    NoSuchVariant {
10        /// The enum definition containing all known variants.
11        enum_type: EnumType,
12    },
13
14    /// Tried to get the wrong shape out of a value — e.g. we were manipulating
15    /// a `String`, but `.get()` was called with a `u64` or something.
16    WrongShape {
17        /// The expected shape of the value.
18        expected: &'static Shape,
19        /// The actual shape of the value.
20        actual: &'static Shape,
21    },
22
23    /// Attempted to perform an operation that expected a struct or something
24    WasNotA {
25        /// The name of the expected type.
26        expected: &'static str,
27
28        /// The type we got instead
29        actual: &'static Shape,
30    },
31
32    /// A field was not initialized during build
33    UninitializedField {
34        /// The shape containing the field
35        shape: &'static Shape,
36        /// The name of the field that wasn't initialized
37        field_name: &'static str,
38    },
39
40    /// A field in an enum variant was not initialized during build
41    UninitializedEnumField {
42        /// The enum shape
43        shape: &'static Shape,
44        /// The name of the field that wasn't initialized
45        field_name: &'static str,
46        /// The name of the variant containing the field
47        variant_name: &'static str,
48    },
49
50    /// An enum had no variant selected during build
51    NoVariantSelected {
52        /// The enum shape
53        shape: &'static Shape,
54    },
55
56    /// A scalar value was not initialized during build
57    UninitializedValue {
58        /// The scalar shape
59        shape: &'static Shape,
60    },
61
62    /// An invariant of the reflection system was violated.
63    InvariantViolation {
64        /// The invariant that was violated.
65        invariant: &'static str,
66    },
67
68    /// Attempted to set a value to its default, but the value doesn't implement `Default`.
69    MissingCharacteristic {
70        /// The shape of the value that doesn't implement `Default`.
71        shape: &'static Shape,
72        /// The characteristic that is missing.
73        characteristic: Characteristic,
74    },
75
76    /// An operation failed for a given shape
77    OperationFailed {
78        /// The shape of the value for which the operation failed.
79        shape: &'static Shape,
80        /// The name of the operation that failed.
81        operation: &'static str,
82    },
83
84    /// An error occurred when attempting to access or modify a field.
85    FieldError {
86        /// The shape of the value containing the field.
87        shape: &'static Shape,
88        /// The specific error that occurred with the field.
89        field_error: FieldError,
90    },
91
92    /// An unknown error occurred.
93    Unknown,
94
95    /// An error occured while putting
96    TryFromError {
97        /// The shape of the value being converted from.
98        src_shape: &'static Shape,
99
100        /// The shape of the value being converted to.
101        dst_shape: &'static Shape,
102
103        /// The inner error
104        inner: TryFromError,
105    },
106
107    /// A shape has a `default` attribute, but no implementation of the `Default` trait.
108    DefaultAttrButNoDefaultImpl {
109        /// The shape of the value that has a `default` attribute but no default implementation.
110        shape: &'static Shape,
111    },
112
113    /// The type is unsized
114    Unsized {
115        /// The shape for the type that is unsized
116        shape: &'static Shape,
117    },
118
119    /// Array not fully initialized during build
120    ArrayNotFullyInitialized {
121        /// The shape of the array
122        shape: &'static Shape,
123        /// The number of elements pushed
124        pushed_count: usize,
125        /// The expected array size
126        expected_size: usize,
127    },
128
129    /// Array index out of bounds
130    ArrayIndexOutOfBounds {
131        /// The shape of the array
132        shape: &'static Shape,
133        /// The index that was out of bounds
134        index: usize,
135        /// The array size
136        size: usize,
137    },
138}
139
140impl core::fmt::Display for ReflectError {
141    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
142        match self {
143            ReflectError::NoSuchVariant { enum_type } => {
144                write!(f, "No such variant in enum. Known variants: ")?;
145                for v in enum_type.variants {
146                    write!(f, ", {}", v.name.cyan())?;
147                }
148                write!(f, ", that's it.")
149            }
150            ReflectError::WrongShape { expected, actual } => {
151                write!(
152                    f,
153                    "Wrong shape: expected {}, but got {}",
154                    expected.green(),
155                    actual.red()
156                )
157            }
158            ReflectError::WasNotA { expected, actual } => {
159                write!(
160                    f,
161                    "Wrong shape: expected {}, but got {}",
162                    expected.green(),
163                    actual.red()
164                )
165            }
166            ReflectError::UninitializedField { shape, field_name } => {
167                write!(f, "Field '{}::{}' was not initialized", shape, field_name)
168            }
169            ReflectError::UninitializedEnumField {
170                shape,
171                field_name,
172                variant_name,
173            } => {
174                write!(
175                    f,
176                    "Field '{}::{}' in variant '{}' was not initialized",
177                    shape.blue(),
178                    field_name.yellow(),
179                    variant_name.red()
180                )
181            }
182            ReflectError::NoVariantSelected { shape } => {
183                write!(f, "Enum '{}' had no variant selected", shape.blue())
184            }
185            ReflectError::UninitializedValue { shape } => {
186                write!(f, "Value '{}' was not initialized", shape.blue())
187            }
188            ReflectError::InvariantViolation { invariant } => {
189                write!(f, "Invariant violation: {}", invariant.red())
190            }
191            ReflectError::MissingCharacteristic {
192                shape,
193                characteristic,
194            } => write!(
195                f,
196                "{shape} does not implement characteristic {characteristic:?}",
197            ),
198            ReflectError::OperationFailed { shape, operation } => {
199                write!(
200                    f,
201                    "Operation failed on shape {}: {}",
202                    shape.blue(),
203                    operation
204                )
205            }
206            ReflectError::FieldError { shape, field_error } => {
207                write!(f, "Field error for shape {}: {}", shape.red(), field_error)
208            }
209            ReflectError::Unknown => write!(f, "Unknown error"),
210            ReflectError::TryFromError {
211                src_shape,
212                dst_shape,
213                inner,
214            } => {
215                write!(
216                    f,
217                    "While trying to put {} into a {}: {}",
218                    src_shape.green(),
219                    dst_shape.blue(),
220                    inner.red()
221                )
222            }
223            ReflectError::DefaultAttrButNoDefaultImpl { shape } => write!(
224                f,
225                "Shape '{}' has a `default` attribute but no default implementation",
226                shape.red()
227            ),
228            ReflectError::Unsized { shape } => write!(f, "Shape '{}' is unsized", shape.red()),
229            ReflectError::ArrayNotFullyInitialized {
230                shape,
231                pushed_count,
232                expected_size,
233            } => {
234                write!(
235                    f,
236                    "Array '{}' not fully initialized: expected {} elements, but got {}",
237                    shape.blue(),
238                    expected_size,
239                    pushed_count
240                )
241            }
242            ReflectError::ArrayIndexOutOfBounds { shape, index, size } => {
243                write!(
244                    f,
245                    "Array index {} out of bounds for '{}' (array length is {})",
246                    index,
247                    shape.blue(),
248                    size
249                )
250            }
251        }
252    }
253}
254
255impl core::error::Error for ReflectError {}