geam_core/runtime/error/
invariant.rs1use crate::plan::execution::function::FunctionReturnFamily;
2use crate::plan::{CustomType, ValueType};
3use ecow::EcoString;
4
5#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
6pub enum InvariantError {
7 #[error("function return family mismatch (expected {expected}, got {actual})")]
8 FunctionReturnFamilyMismatch {
9 expected: FunctionReturnFamily,
10 actual: FunctionReturnFamily,
11 },
12 #[error("tuple index family mismatch (expected {expected:?}, got {actual:?})")]
13 TupleIndexFamilyMismatch {
14 expected: ValueType,
15 actual: ValueType,
16 },
17 #[error(
18 "custom field family mismatch in {custom_type:?}::{constructor} field {field_index} (expected {expected:?}, got {actual:?})"
19 )]
20 CustomFieldFamilyMismatch {
21 custom_type: CustomType,
22 constructor: EcoString,
23 field_index: usize,
24 expected: ValueType,
25 actual: ValueType,
26 },
27 #[error("list index out of bounds for {item_type:?} list (index {index}, length {length})")]
28 ListIndexOutOfBounds {
29 item_type: ValueType,
30 index: usize,
31 length: usize,
32 },
33}
34
35#[cfg(test)]
36mod tests {
37 use super::InvariantError;
38 use crate::plan::execution::function::FunctionReturnFamily;
39 use crate::plan::{CustomType, CustomTypeName, ValueType};
40
41 #[test]
42 fn function_return_family_mismatch_display() {
43 let error = InvariantError::FunctionReturnFamilyMismatch {
44 expected: FunctionReturnFamily::Int,
45 actual: FunctionReturnFamily::String,
46 };
47
48 assert_eq!(
49 error.to_string(),
50 "function return family mismatch (expected Int, got String)",
51 );
52 }
53
54 #[test]
55 fn tuple_index_family_mismatch_display() {
56 let error = InvariantError::TupleIndexFamilyMismatch {
57 expected: ValueType::Tuple(vec![ValueType::Int]),
58 actual: ValueType::String,
59 };
60
61 assert_eq!(
62 error.to_string(),
63 "tuple index family mismatch (expected Tuple([Int]), got String)",
64 );
65 }
66
67 #[test]
68 fn list_index_out_of_bounds_display() {
69 let error = InvariantError::ListIndexOutOfBounds {
70 item_type: ValueType::Int,
71 index: 1,
72 length: 1,
73 };
74
75 assert_eq!(
76 error.to_string(),
77 "list index out of bounds for Int list (index 1, length 1)",
78 );
79 }
80
81 #[test]
82 fn custom_field_family_mismatch_display() {
83 let error = InvariantError::CustomFieldFamilyMismatch {
84 custom_type: CustomType::new(
85 CustomTypeName::new("app".into(), "main".into(), "Box".into()),
86 vec![ValueType::Int],
87 ),
88 constructor: "Box".into(),
89 field_index: 0,
90 expected: ValueType::Int,
91 actual: ValueType::String,
92 };
93
94 assert_eq!(
95 error.to_string(),
96 "custom field family mismatch in CustomType { name: CustomTypeName { package: \"app\", module: \"main\", name: \"Box\" }, arguments: [Int] }::Box field 0 (expected Int, got String)",
97 );
98 }
99}