icydb_core/db/schema/
errors.rs1use crate::db::predicate::{CoercionId, CompareOp};
7use std::fmt;
8
9#[derive(Clone, Debug, Eq, PartialEq)]
11pub enum SchemaValidationOperator {
12 Compare(CompareOp),
13 CompareField { op: CompareOp, right_field: String },
14 IsEmpty,
15 IsNotEmpty,
16 TextContains,
17 TextContainsCi,
18}
19
20impl SchemaValidationOperator {
21 #[cfg(any(test, feature = "query"))]
22 pub(crate) const fn compare(op: CompareOp) -> Self {
23 Self::Compare(op)
24 }
25
26 #[cfg(any(test, feature = "query"))]
27 pub(crate) fn compare_field(op: CompareOp, right_field: &str) -> Self {
28 Self::CompareField {
29 op,
30 right_field: right_field.to_string(),
31 }
32 }
33}
34
35impl fmt::Display for SchemaValidationOperator {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self {
38 Self::Compare(op) => write!(f, "{op:?}"),
39 Self::CompareField { op, right_field } => {
40 write!(f, "{op:?} against field '{right_field}'")
41 }
42 Self::IsEmpty => f.write_str("is_empty"),
43 Self::IsNotEmpty => f.write_str("is_not_empty"),
44 Self::TextContains => f.write_str("text_contains"),
45 Self::TextContainsCi => f.write_str("text_contains_ci"),
46 }
47 }
48}
49
50#[derive(Clone, Copy, Debug, Eq, PartialEq)]
52pub enum SchemaLiteralValidationReason {
53 ExpectedList,
54 ExpectedText,
55 ExpectedScalar,
56 LiteralTypeMismatch,
57 ListElementTypeMismatch,
58 EnumPathMismatch,
59 UnknownEnumVariant,
60 EnumBodyMismatch,
61}
62
63impl fmt::Display for SchemaLiteralValidationReason {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 match self {
66 Self::ExpectedList => f.write_str("expected list literal"),
67 Self::ExpectedText => f.write_str("expected text literal"),
68 Self::ExpectedScalar => f.write_str("expected scalar literal"),
69 Self::LiteralTypeMismatch => f.write_str("literal type does not match field type"),
70 Self::ListElementTypeMismatch => {
71 f.write_str("list literal does not match field element type")
72 }
73 Self::EnumPathMismatch => f.write_str("enum path does not match field enum type"),
74 Self::UnknownEnumVariant => f.write_str("enum variant is not accepted for field type"),
75 Self::EnumBodyMismatch => {
76 f.write_str("enum payload does not match the accepted variant contract")
77 }
78 }
79 }
80}
81
82#[derive(Debug, thiserror::Error)]
84pub enum ValidateError {
85 #[error("unknown field '{field}'")]
86 UnknownField { field: String },
87
88 #[error("field '{field}' is not queryable")]
89 NonQueryableFieldType { field: String },
90
91 #[error("duplicate field '{field}'")]
92 DuplicateField { field: String },
93
94 #[error("map predicates are unsupported for field '{field}'")]
95 MapPredicateUnsupported { field: String },
96
97 #[error("primary key '{field}' not present in entity fields")]
98 InvalidPrimaryKey { field: String },
99
100 #[error("primary key '{field}' has a non-keyable type")]
101 InvalidPrimaryKeyType { field: String },
102
103 #[error("duplicate index name '{name}'")]
104 DuplicateIndexName { name: String },
105
106 #[error("operator {operator} is not valid for field '{field}'")]
107 InvalidOperator {
108 field: String,
109 operator: SchemaValidationOperator,
110 },
111
112 #[error("coercion {coercion:?} is not valid for field '{field}'")]
113 InvalidCoercion { field: String, coercion: CoercionId },
114
115 #[error("invalid literal for field '{field}': {reason}")]
116 InvalidLiteral {
117 field: String,
118 reason: SchemaLiteralValidationReason,
119 },
120}
121
122impl ValidateError {
123 #[cfg(any(test, feature = "query"))]
124 pub(crate) fn invalid_operator(field: &str, operator: SchemaValidationOperator) -> Self {
125 Self::InvalidOperator {
126 field: field.to_string(),
127 operator,
128 }
129 }
130
131 #[cfg(any(test, feature = "query"))]
132 pub(crate) fn invalid_literal(field: &str, reason: SchemaLiteralValidationReason) -> Self {
133 Self::InvalidLiteral {
134 field: field.to_string(),
135 reason,
136 }
137 }
138}