facet_reflect/
error.rs

1use facet_core::{Characteristic, EnumDef, 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_def: EnumDef,
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
120impl core::fmt::Display for ReflectError {
121    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
122        match self {
123            ReflectError::PartiallyInitialized { field } => {
124                write!(
125                    f,
126                    "Value partially initialized: field {} was not set",
127                    field.name
128                )
129            }
130            ReflectError::NoSuchVariant { enum_def } => {
131                write!(f, "No such variant in enum. Known variants: ")?;
132                for v in enum_def.variants {
133                    write!(f, ", {}", v.name)?;
134                }
135                write!(f, ", that's it.")
136            }
137            ReflectError::WrongShape { expected, actual } => {
138                write!(
139                    f,
140                    "Wrong shape: expected {}, but got {}",
141                    expected.green(),
142                    actual.red()
143                )
144            }
145            ReflectError::WasNotA { expected, actual } => {
146                write!(
147                    f,
148                    "Wrong shape: expected {}, but got {}",
149                    expected.green(),
150                    actual.red()
151                )
152            }
153            ReflectError::UninitializedField { shape, field_name } => {
154                write!(f, "Field '{}::{}' was not initialized", shape, field_name)
155            }
156            ReflectError::UninitializedEnumField {
157                shape,
158                field_name,
159                variant_name,
160            } => {
161                write!(
162                    f,
163                    "Field '{}::{}' in variant '{}' was not initialized",
164                    shape, field_name, variant_name
165                )
166            }
167            ReflectError::NoVariantSelected { shape } => {
168                write!(f, "Enum '{}' had no variant selected", shape)
169            }
170            ReflectError::UninitializedValue { shape } => {
171                write!(f, "Value '{}' was not initialized", shape)
172            }
173            ReflectError::InvariantViolation { invariant } => {
174                write!(f, "Invariant violation: {}", invariant)
175            }
176            ReflectError::MissingCharacteristic {
177                shape,
178                characteristic,
179            } => write!(
180                f,
181                "{shape} does not implement characteristic {characteristic:?}",
182            ),
183            ReflectError::OperationFailed { shape, operation } => {
184                write!(f, "Operation '{}' failed for shape {}", operation, shape)
185            }
186            ReflectError::FieldError { shape, field_error } => {
187                write!(f, "Field error for shape {}: {}", shape, field_error)
188            }
189            ReflectError::Unknown => write!(f, "Unknown error"),
190            ReflectError::TryFromError {
191                src_shape,
192                dst_shape,
193                inner,
194            } => {
195                write!(
196                    f,
197                    "While trying to put {} into a {}: {}",
198                    src_shape.green(),
199                    dst_shape.blue(),
200                    inner.red()
201                )
202            }
203            ReflectError::DefaultAttrButNoDefaultImpl { shape } => write!(
204                f,
205                "Shape '{}' has a `default` attribute but no default implementation",
206                shape
207            ),
208        }
209    }
210}
211
212impl core::error::Error for ReflectError {}