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