facet_reflect/
error.rs

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