1use std::fmt;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct HaysonSchemaError(pub String);
5
6impl fmt::Display for HaysonSchemaError {
7 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8 write!(f, "{}", self.0)
9 }
10}
11
12impl std::error::Error for HaysonSchemaError {}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct ValidationIssue {
16 pub field: String,
17 pub reason: String,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct HaysonValidationError {
22 pub table: String,
23 pub issues: Vec<ValidationIssue>,
24}
25
26impl fmt::Display for HaysonValidationError {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 let detail = self
29 .issues
30 .iter()
31 .map(|issue| format!("{}: {}", issue.field, issue.reason))
32 .collect::<Vec<_>>()
33 .join("; ");
34 write!(f, "record rejected by schema of table \"{}\" — {}", self.table, detail)
35 }
36}
37
38impl std::error::Error for HaysonValidationError {}
39
40#[derive(Debug, Clone, PartialEq, Eq)]
41pub struct HaysonUniqueViolationError {
42 pub table: String,
43 pub field: String,
44 pub holder: String,
45}
46
47impl fmt::Display for HaysonUniqueViolationError {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 write!(
50 f,
51 "unique field \"{}\" of table \"{}\" is already taken by key \"{}\"",
52 self.field, self.table, self.holder
53 )
54 }
55}
56
57impl std::error::Error for HaysonUniqueViolationError {}
58
59#[derive(Debug, Clone, PartialEq, Eq)]
62pub struct HaysonRelationViolationError {
63 pub relation: String,
64 pub table: String,
65 pub field: String,
66 pub value: String,
67}
68
69impl fmt::Display for HaysonRelationViolationError {
70 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71 write!(
72 f,
73 "relation \"{}\" refuses \"{}\".\"{}\" = {}: no record on the other side of the relation matches it",
74 self.relation, self.table, self.field, self.value
75 )
76 }
77}
78
79impl std::error::Error for HaysonRelationViolationError {}
80
81#[derive(Debug, Clone, PartialEq, Eq)]
85pub struct HaysonRelationRestrictError {
86 pub relation: String,
87 pub table: String,
88 pub key: String,
89 pub referencing_table: String,
90 pub referencing_field: String,
91 pub referencing: usize,
92}
93
94impl fmt::Display for HaysonRelationRestrictError {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(
97 f,
98 "relation \"{}\" refuses deleting \"{}\".\"{}\": {} record(s) of \"{}\" still point at it through \"{}\"",
99 self.relation, self.table, self.key, self.referencing, self.referencing_table, self.referencing_field
100 )
101 }
102}
103
104impl std::error::Error for HaysonRelationRestrictError {}
105
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct HaysonPendingConflictError {
108 pub table: String,
109 pub key: String,
110 pub fields: Vec<String>,
111}
112
113impl fmt::Display for HaysonPendingConflictError {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 let list = self
116 .fields
117 .iter()
118 .map(|field| format!("\"{field}\""))
119 .collect::<Vec<_>>()
120 .join(", ");
121 write!(
122 f,
123 "key \"{}\" of table \"{}\" already has a queued change on {} — pass force to overwrite it",
124 self.key, self.table, list
125 )
126 }
127}
128
129impl std::error::Error for HaysonPendingConflictError {}
130
131#[derive(Debug, Clone, PartialEq, Eq)]
132pub struct HaysonCorruptLogError {
133 pub path: String,
134 pub offset: u64,
135 pub reason: String,
136}
137
138impl fmt::Display for HaysonCorruptLogError {
139 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
140 write!(
141 f,
142 "log \"{}\" is corrupt at offset {}: {}",
143 self.path, self.offset, self.reason
144 )
145 }
146}
147
148impl std::error::Error for HaysonCorruptLogError {}
149
150#[derive(Debug, Clone, PartialEq, Eq)]
151pub struct HaysonIndexMismatchError {
152 pub path: String,
153 pub log_path: String,
156 pub watermark: u64,
159 pub expected_hash: String,
160 pub actual_hash: String,
161}
162
163impl fmt::Display for HaysonIndexMismatchError {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 write!(
166 f,
167 "snapshot \"{}\" claims watermark and schema match the log, but its content fingerprint ({}) does not match the log's ({}) — left on disk for inspection, not silently discarded",
168 self.path, self.expected_hash, self.actual_hash
169 )
170 }
171}
172
173impl std::error::Error for HaysonIndexMismatchError {}
174
175#[derive(Debug, Clone, PartialEq, Eq)]
176pub struct HaysonNotFoundError {
177 pub table: String,
178 pub key: String,
179}
180
181impl fmt::Display for HaysonNotFoundError {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 write!(f, "key \"{}\" is not in table \"{}\"", self.key, self.table)
184 }
185}
186
187impl std::error::Error for HaysonNotFoundError {}
188
189#[derive(Debug, Clone, PartialEq, Eq)]
190pub struct HaysonQueryParseError {
191 pub position: usize,
192 pub reason: String,
193}
194
195impl fmt::Display for HaysonQueryParseError {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 write!(
198 f,
199 "query text is invalid at position {}: {}",
200 self.position, self.reason
201 )
202 }
203}
204
205impl std::error::Error for HaysonQueryParseError {}
206
207#[derive(Debug, Clone, PartialEq, Eq)]
210pub struct HaysonPartitionError {
211 pub table: String,
212 pub field: String,
213 pub reason: String,
214}
215
216impl HaysonPartitionError {
217 pub fn new(table: impl Into<String>, field: impl Into<String>, reason: impl Into<String>) -> Self {
218 HaysonPartitionError {
219 table: table.into(),
220 field: field.into(),
221 reason: reason.into(),
222 }
223 }
224}
225
226impl fmt::Display for HaysonPartitionError {
227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228 write!(
229 f,
230 "partition field \"{}\" of table \"{}\": {}",
231 self.field, self.table, self.reason
232 )
233 }
234}
235
236impl std::error::Error for HaysonPartitionError {}
237
238#[derive(Debug, Clone, PartialEq, Eq)]
241pub struct HaysonCipherError {
242 pub table: String,
243 pub field: String,
244 pub reason: String,
245 pub key_id: Option<String>,
246}
247
248impl HaysonCipherError {
249 pub fn new(table: impl Into<String>, field: impl Into<String>, reason: impl Into<String>) -> Self {
250 HaysonCipherError {
251 table: table.into(),
252 field: field.into(),
253 reason: reason.into(),
254 key_id: None,
255 }
256 }
257
258 pub fn with_key_id(mut self, key_id: impl Into<String>) -> Self {
259 self.key_id = Some(key_id.into());
260 self
261 }
262}
263
264impl fmt::Display for HaysonCipherError {
265 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266 if self.table.is_empty() {
267 write!(f, "cypher configuration {}", self.reason)
268 } else {
269 write!(
270 f,
271 "encrypted field \"{}\" of table \"{}\" {}",
272 self.field, self.table, self.reason
273 )
274 }
275 }
276}
277
278impl std::error::Error for HaysonCipherError {}