1use std::{error::Error as _, fmt};
19
20use crate::{
21 schema::{Name, RecordSchema, Schema, SchemaKind, UnionSchema},
22 types::{Value, ValueKind},
23};
24
25#[derive(thiserror::Error, Debug)]
32#[repr(transparent)]
33#[error(transparent)]
34pub struct Error {
35 details: Box<Details>,
36}
37
38impl Error {
39 pub fn new(details: Details) -> Self {
40 Self {
41 details: Box::new(details),
42 }
43 }
44
45 pub fn details(&self) -> &Details {
46 &self.details
47 }
48
49 pub fn into_details(self) -> Details {
50 *self.details
51 }
52}
53
54impl From<Details> for Error {
55 fn from(details: Details) -> Self {
56 Self::new(details)
57 }
58}
59
60impl serde::ser::Error for Error {
61 fn custom<T: fmt::Display>(msg: T) -> Self {
62 Self::new(<Details as serde::ser::Error>::custom(msg))
63 }
64}
65
66impl serde::de::Error for Error {
67 fn custom<T: fmt::Display>(msg: T) -> Self {
68 Self::new(<Details as serde::de::Error>::custom(msg))
69 }
70}
71
72#[derive(thiserror::Error)]
73pub enum Details {
74 #[error("Bad Snappy CRC32; expected {expected:x} but got {actual:x}")]
75 SnappyCrc32 { expected: u32, actual: u32 },
76
77 #[error("Invalid u8 for bool: {0}")]
78 BoolValue(u8),
79
80 #[error("Not a fixed value, required for decimal with fixed schema: {0:?}")]
81 FixedValue(Value),
82
83 #[error("Not a bytes value, required for decimal with bytes schema: {0:?}")]
84 BytesValue(Value),
85
86 #[error("Not a string value, required for uuid: {0:?}")]
87 GetUuidFromStringValue(Value),
88
89 #[error("Two schemas with the same fullname were given: {0:?}")]
90 NameCollision(String),
91
92 #[error("Not a fixed or bytes type, required for decimal schema, got: {0:?}")]
93 ResolveDecimalSchema(SchemaKind),
94
95 #[error("Invalid utf-8 string")]
96 ConvertToUtf8(#[source] std::string::FromUtf8Error),
97
98 #[error("Invalid utf-8 string")]
99 ConvertToUtf8Error(#[source] std::str::Utf8Error),
100
101 #[error("Value does not match schema")]
103 Validation,
104
105 #[error("Value {value:?} does not match schema {schema:?}: Reason: {reason}")]
107 ValidationWithReason {
108 value: Value,
109 schema: Schema,
110 reason: String,
111 },
112
113 #[error(
114 "Unable to allocate {desired} bytes (maximum allowed: {maximum}). Change the limit using `apache_avro::util::max_allocation_bytes`"
115 )]
116 MemoryAllocation { desired: usize, maximum: usize },
117
118 #[error(
120 "Number of bytes requested for decimal sign extension {requested} is less than the number of bytes needed to decode {needed}"
121 )]
122 SignExtend { requested: usize, needed: usize },
123
124 #[error("Failed to read boolean bytes: {0}")]
125 ReadBoolean(#[source] std::io::Error),
126
127 #[error("Failed to read bytes: {0}")]
128 ReadBytes(#[source] std::io::Error),
129
130 #[error("Failed to read string: {0}")]
131 ReadString(#[source] std::io::Error),
132
133 #[error("Failed to read double: {0}")]
134 ReadDouble(#[source] std::io::Error),
135
136 #[error("Failed to read float: {0}")]
137 ReadFloat(#[source] std::io::Error),
138
139 #[error("Failed to read duration: {0}")]
140 ReadDuration(#[source] std::io::Error),
141
142 #[error("Failed to read fixed number of bytes '{1}': : {0}")]
143 ReadFixed(#[source] std::io::Error, usize),
144
145 #[error("Failed to convert &str to UUID: {0}")]
146 ConvertStrToUuid(#[source] uuid::Error),
147
148 #[error("Failed to convert Fixed bytes to UUID. It must be exactly 16 bytes, got {0}")]
149 ConvertFixedToUuid(usize),
150
151 #[error("Failed to convert Fixed bytes to UUID: {0}")]
152 ConvertSliceToUuid(#[source] uuid::Error),
153
154 #[error("Map key is not a string; key type is {0:?}")]
155 MapKeyType(ValueKind),
156
157 #[error("Union index {index} out of bounds: {num_variants}")]
158 GetUnionVariant { index: i64, num_variants: usize },
159
160 #[error(
161 "Enum symbol index out of bounds: got {index} but there are only {num_variants} variants"
162 )]
163 EnumSymbolIndex { index: usize, num_variants: usize },
164
165 #[error("Enum symbol not found {0}")]
166 GetEnumSymbol(String),
167
168 #[error("Unable to decode enum index")]
169 GetEnumUnknownIndexValue,
170
171 #[error("Scale {scale} is greater than precision {precision}")]
172 GetScaleAndPrecision { scale: usize, precision: usize },
173
174 #[error(
175 "Fixed type number of bytes {size} is not large enough to hold decimal values of precision {precision}"
176 )]
177 GetScaleWithFixedSize { size: usize, precision: usize },
178
179 #[error("Expected Value::Uuid, got: {0:?}")]
180 GetUuid(Value),
181
182 #[error("Expected Value::BigDecimal, got: {0:?}")]
183 GetBigDecimal(Value),
184
185 #[error("Fixed bytes of size 12 expected, got Fixed of size {0}")]
186 GetDurationFixedBytes(usize),
187
188 #[error("Expected Value::Duration or Value::Fixed(12), got: {0:?}")]
189 ResolveDuration(Value),
190
191 #[error("Expected Value::Decimal, Value::Bytes or Value::Fixed, got: {0:?}")]
192 ResolveDecimal(Value),
193
194 #[error("Missing field in record: {0:?}")]
195 GetField(String),
196
197 #[error("Unable to convert to u8, got {0:?}")]
198 GetU8(Value),
199
200 #[error("Precision {precision} too small to hold decimal values with {num_bytes} bytes")]
201 ComparePrecisionAndSize { precision: usize, num_bytes: usize },
202
203 #[error("Cannot convert length to i32: {1}")]
204 ConvertLengthToI32(#[source] std::num::TryFromIntError, usize),
205
206 #[error("Expected Value::Date or Value::Int, got: {0:?}")]
207 GetDate(Value),
208
209 #[error("Expected Value::TimeMillis or Value::Int, got: {0:?}")]
210 GetTimeMillis(Value),
211
212 #[error("Expected Value::TimeMicros, Value::Long or Value::Int, got: {0:?}")]
213 GetTimeMicros(Value),
214
215 #[error("Expected Value::TimestampMillis, Value::Long or Value::Int, got: {0:?}")]
216 GetTimestampMillis(Value),
217
218 #[error("Expected Value::TimestampMicros, Value::Long or Value::Int, got: {0:?}")]
219 GetTimestampMicros(Value),
220
221 #[error("Expected Value::TimestampNanos, Value::Long or Value::Int, got: {0:?}")]
222 GetTimestampNanos(Value),
223
224 #[error("Expected Value::LocalTimestampMillis, Value::Long or Value::Int, got: {0:?}")]
225 GetLocalTimestampMillis(Value),
226
227 #[error("Expected Value::LocalTimestampMicros, Value::Long or Value::Int, got: {0:?}")]
228 GetLocalTimestampMicros(Value),
229
230 #[error("Expected Value::LocalTimestampNanos, Value::Long or Value::Int, got: {0:?}")]
231 GetLocalTimestampNanos(Value),
232
233 #[error("Expected Value::Null, got: {0:?}")]
234 GetNull(Value),
235
236 #[error("Expected Value::Boolean, got: {0:?}")]
237 GetBoolean(Value),
238
239 #[error("Expected Value::Int, got: {0:?}")]
240 GetInt(Value),
241
242 #[error("Expected Value::Long or Value::Int, got: {0:?}")]
243 GetLong(Value),
244
245 #[error(r#"Expected Value::Double, Value::Float, Value::Int, Value::Long or Value::String ("NaN", "INF", "Infinity", "-INF" or "-Infinity"), got: {0:?}"#)]
246 GetDouble(Value),
247
248 #[error(r#"Expected Value::Float, Value::Double, Value::Int, Value::Long or Value::String ("NaN", "INF", "Infinity", "-INF" or "-Infinity"), got: {0:?}"#)]
249 GetFloat(Value),
250
251 #[error("Expected Value::Bytes, got: {0:?}")]
252 GetBytes(Value),
253
254 #[error("Expected Value::String, Value::Bytes or Value::Fixed, got: {0:?}")]
255 GetString(Value),
256
257 #[error("Expected Value::Enum, got: {0:?}")]
258 GetEnum(Value),
259
260 #[error("Fixed size mismatch, expected: {size}, got: {n}")]
261 CompareFixedSizes { size: usize, n: usize },
262
263 #[error("String expected for fixed, got: {0:?}")]
264 GetStringForFixed(Value),
265
266 #[error("Enum default {symbol:?} is not among allowed symbols {symbols:?}")]
267 GetEnumDefault {
268 symbol: String,
269 symbols: Vec<String>,
270 },
271
272 #[error("Enum value index {index} is out of bounds {nsymbols}")]
273 GetEnumValue { index: usize, nsymbols: usize },
274
275 #[error("Key {0} not found in decimal metadata JSON")]
276 GetDecimalMetadataFromJson(&'static str),
277
278 #[error("Could not find matching type in {schema:?} for {value:?}")]
279 FindUnionVariant { schema: UnionSchema, value: Value },
280
281 #[error("Union type should not be empty")]
282 EmptyUnion,
283
284 #[error("Array({expected:?}) expected, got {other:?}")]
285 GetArray { expected: SchemaKind, other: Value },
286
287 #[error("Map({expected:?}) expected, got {other:?}")]
288 GetMap { expected: SchemaKind, other: Value },
289
290 #[error("Record with fields {expected:?} expected, got {other:?}")]
291 GetRecord {
292 expected: Vec<(String, SchemaKind)>,
293 other: Value,
294 },
295
296 #[error("No `name` field")]
297 GetNameField,
298
299 #[error("No `name` in record field")]
300 GetNameFieldFromRecord,
301
302 #[error("Unions may not directly contain a union")]
303 GetNestedUnion,
304
305 #[error(
306 "Found two different maps while building Union: Schema::Map({0:?}), Schema::Map({1:?})"
307 )]
308 GetUnionDuplicateMap(Schema, Schema),
309
310 #[error(
311 "Found two different arrays while building Union: Schema::Array({0:?}), Schema::Array({1:?})"
312 )]
313 GetUnionDuplicateArray(Schema, Schema),
314
315 #[error("Unions cannot contain duplicate types, found at least two {0:?}")]
316 GetUnionDuplicate(SchemaKind),
317
318 #[error("Unions cannot contain more than one named schema with the same name: {0}")]
319 GetUnionDuplicateNamedSchemas(String),
320
321 #[error("One union type {0:?} must match the `default`'s value type {1:?}")]
322 GetDefaultUnion(SchemaKind, ValueKind),
323
324 #[error("`default`'s value type of field `{0}` in `{1}` must be a `{2:#}`. Got: {3:?}")]
325 GetDefaultRecordField(String, String, String, serde_json::Value),
326
327 #[error("JSON number {0} could not be converted into an Avro value as it's too large")]
328 JsonNumberTooLarge(serde_json::Number),
329
330 #[error("JSON value {0} claims to be u64 but cannot be converted")]
331 GetU64FromJson(serde_json::Number),
332
333 #[error("JSON value {0} claims to be i64 but cannot be converted")]
334 GetI64FromJson(serde_json::Number),
335
336 #[error("Cannot convert u64 to usize: {1}")]
337 ConvertU64ToUsize(#[source] std::num::TryFromIntError, u64),
338
339 #[deprecated(since = "0.20.0", note = "This error variant is not generated anymore")]
340 #[error("Cannot convert u32 to usize: {1}")]
341 ConvertU32ToUsize(#[source] std::num::TryFromIntError, u32),
342
343 #[error("Cannot convert i64 to usize: {1}")]
344 ConvertI64ToUsize(#[source] std::num::TryFromIntError, i64),
345
346 #[error("Cannot convert i32 to usize: {1}")]
347 ConvertI32ToUsize(#[source] std::num::TryFromIntError, i32),
348
349 #[error("Cannot convert i64 to u64: {1}")]
350 ConvertI64ToU64(#[source] std::num::TryFromIntError, i64),
351
352 #[error("Cannot convert i32 to u64: {1}")]
353 ConvertI32ToU64(#[source] std::num::TryFromIntError, i32),
354
355 #[error("Cannot convert i64 to u128: {1}")]
356 ConvertI64ToU128(#[source] std::num::TryFromIntError, i64),
357
358 #[error("Cannot convert i32 to u128: {1}")]
359 ConvertI32ToU128(#[source] std::num::TryFromIntError, i32),
360
361 #[error("Cannot convert usize to i64: {1}")]
362 ConvertUsizeToI64(#[source] std::num::TryFromIntError, usize),
363
364 #[error("Invalid JSON value for decimal precision/scale integer: {0}")]
365 GetPrecisionOrScaleFromJson(serde_json::Number),
366
367 #[error("Failed to parse schema from JSON")]
368 ParseSchemaJson(#[source] serde_json::Error),
369
370 #[error("Failed to read schema")]
371 ReadSchemaFromReader(#[source] std::io::Error),
372
373 #[error("Must be a JSON string, object or array")]
374 ParseSchemaFromValidJson,
375
376 #[error("Unknown primitive type: {0}")]
377 ParsePrimitive(String),
378
379 #[error("Unknown primitive type: '{0}'. Did you mean '{1}' ?")]
380 ParsePrimitiveSimilar(String, &'static str),
381
382 #[error("invalid JSON for {key:?}: {value:?}")]
383 GetDecimalMetadataValueFromJson {
384 key: String,
385 value: serde_json::Value,
386 },
387
388 #[error("The decimal precision ({precision}) must be bigger or equal to the scale ({scale})")]
389 DecimalPrecisionLessThanScale { precision: usize, scale: usize },
390
391 #[error("The decimal precision ({precision}) must be a positive number")]
392 DecimalPrecisionMuBePositive { precision: usize },
393
394 #[deprecated(since = "0.20.0", note = "This error variant is not generated anymore")]
395 #[error("Unreadable big decimal sign")]
396 BigDecimalSign,
397
398 #[error("Unreadable length for big decimal inner bytes: {0}")]
399 BigDecimalLen(#[source] Box<Error>),
400
401 #[error("Unreadable big decimal scale")]
402 BigDecimalScale,
403
404 #[deprecated(since = "0.20.0", note = "This error variant is not generated anymore")]
405 #[error("Unexpected `type` {0} variant for `logicalType`")]
406 GetLogicalTypeVariant(serde_json::Value),
407
408 #[error("No `type` field found for `logicalType`")]
409 GetLogicalTypeField,
410
411 #[error("logicalType must be a string, but is {0:?}")]
412 GetLogicalTypeFieldType(serde_json::Value),
413
414 #[error("Unknown complex type: {0}")]
415 GetComplexType(serde_json::Value),
416
417 #[error("No `type` in complex type")]
418 GetComplexTypeField,
419
420 #[error("No `type` in record field")]
421 GetRecordFieldTypeField,
422
423 #[error("No `fields` in record")]
424 GetRecordFieldsJson,
425
426 #[error("No `symbols` field in enum")]
427 GetEnumSymbolsField,
428
429 #[error("Unable to parse `symbols` in enum")]
430 GetEnumSymbols,
431
432 #[error("Invalid enum symbol name {0}")]
433 EnumSymbolName(String),
434
435 #[error("Invalid field name {0}")]
436 FieldName(String),
437
438 #[error("Duplicate field name {0}")]
439 FieldNameDuplicate(String),
440
441 #[error("Invalid schema name {0}. It must match the regex '{1}'")]
442 InvalidSchemaName(String, &'static str),
443
444 #[error("Invalid namespace {0}. It must match the regex '{1}'")]
445 InvalidNamespace(String, &'static str),
446
447 #[error(
448 "Invalid schema: There is no type called '{0}', if you meant to define a non-primitive schema, it should be defined inside `type` attribute."
449 )]
450 InvalidSchemaRecord(String),
451
452 #[error("Duplicate enum symbol {0}")]
453 EnumSymbolDuplicate(String),
454
455 #[error("Default value for an enum must be a string! Got: {0}")]
456 EnumDefaultWrongType(serde_json::Value),
457
458 #[error("Default value for an array must be an array! Got: {0}")]
459 ArrayDefaultWrongType(serde_json::Value),
460
461 #[error("Default value for an array must be an array of {0}! Found: {1:?}")]
462 ArrayDefaultWrongInnerType(Schema, Value),
463
464 #[error("Default value for a map must be an object! Got: {0}")]
465 MapDefaultWrongType(serde_json::Value),
466
467 #[error("Default value for a map must be an object with (String, {0})! Found: (String, {1:?})")]
468 MapDefaultWrongInnerType(Schema, Value),
469
470 #[error("No `items` in array")]
471 GetArrayItemsField,
472
473 #[error("No `values` in map")]
474 GetMapValuesField,
475
476 #[error("Fixed schema `size` value must be a positive integer: {0}")]
477 GetFixedSizeFieldPositive(serde_json::Value),
478
479 #[error("Fixed schema has no `size`")]
480 GetFixedSizeField,
481
482 #[deprecated(since = "0.22.0", note = "This error variant is not generated anymore")]
483 #[error("Fixed schema's default value length ({0}) does not match its size ({1})")]
484 FixedDefaultLenSizeMismatch(usize, u64),
485
486 #[deprecated(since = "0.20.0", note = "This error variant is not generated anymore")]
487 #[error("Failed to compress with flate: {0}")]
488 DeflateCompress(#[source] std::io::Error),
489
490 #[deprecated(since = "0.19.0", note = "This error can no longer occur")]
492 #[error("Failed to finish flate compressor: {0}")]
493 DeflateCompressFinish(#[source] std::io::Error),
494
495 #[error("Failed to decompress with flate: {0}")]
496 DeflateDecompress(#[source] std::io::Error),
497
498 #[cfg(feature = "snappy")]
499 #[error("Failed to compress with snappy: {0}")]
500 SnappyCompress(#[source] snap::Error),
501
502 #[cfg(feature = "snappy")]
503 #[error("Failed to get snappy decompression length: {0}")]
504 GetSnappyDecompressLen(#[source] snap::Error),
505
506 #[cfg(feature = "snappy")]
507 #[error("Failed to decompress with snappy: {0}")]
508 SnappyDecompress(#[source] snap::Error),
509
510 #[error("Failed to compress with zstd: {0}")]
511 ZstdCompress(#[source] std::io::Error),
512
513 #[error("Failed to decompress with zstd: {0}")]
514 ZstdDecompress(#[source] std::io::Error),
515
516 #[error("Failed to read header: {0}")]
517 ReadHeader(#[source] std::io::Error),
518
519 #[error("wrong magic in header")]
520 HeaderMagic,
521
522 #[error("Message Header mismatch. Expected: {0:?}. Actual: {1:?}")]
523 SingleObjectHeaderMismatch(Vec<u8>, Vec<u8>),
524
525 #[error("Failed to get JSON from avro.schema key in map")]
526 GetAvroSchemaFromMap,
527
528 #[error("no metadata in header")]
529 GetHeaderMetadata,
530
531 #[error("Failed to read marker bytes: {0}")]
532 ReadMarker(#[source] std::io::Error),
533
534 #[error("Failed to read block marker bytes: {0}")]
535 ReadBlockMarker(#[source] std::io::Error),
536
537 #[error("Read into buffer failed: {0}")]
538 ReadIntoBuf(#[source] std::io::Error),
539
540 #[error(
541 "Invalid sync marker! The sync marker in the data block \
542 doesn't match the file header's sync marker. This likely \
543 indicates data corruption, truncated file, or incorrectly \
544 concatenated Avro files. Verify file integrity and ensure \
545 proper file transmission or creation."
546 )]
547 GetBlockMarker,
548
549 #[error("Overflow when decoding integer value")]
550 IntegerOverflow,
551
552 #[error("Failed to read bytes for decoding variable length integer: {0}")]
553 ReadVariableIntegerBytes(#[source] std::io::Error),
554
555 #[error("Decoded integer out of range for i32: {1}: {0}")]
556 ZagI32(#[source] std::num::TryFromIntError, i64),
557
558 #[error("Did not read any bytes, block is corrupt")]
559 ReadBlock,
560
561 #[error("Failed to serialize value into Avro value: {0}")]
562 SerializeValue(String),
563
564 #[error("Failed to serialize value of type `{value_type}` using Schema::{schema:?}: {value}")]
565 SerializeValueWithSchema {
566 value_type: &'static str,
567 value: String,
568 schema: Schema,
569 },
570
571 #[error("{position} is not a valid index for fields in {schema:?}")]
572 SerializeRecordUnknownFieldIndex {
573 position: usize,
574 schema: RecordSchema,
575 },
576
577 #[error("Failed to serialize field '{field_name}' of record {record_schema:?}: {error}")]
578 SerializeRecordFieldWithSchema {
579 field_name: String,
580 record_schema: RecordSchema,
581 error: String,
582 },
583
584 #[error("Missing default for skipped field '{field_name}' of schema {schema:?}")]
585 MissingDefaultForSkippedField {
586 field_name: String,
587 schema: RecordSchema,
588 },
589
590 #[error("Failed to deserialize Avro value into value: {0}")]
591 DeserializeValue(String),
592
593 #[error("Failed to deserialize value of type {value_type} using schema {schema:?}: {value}")]
594 DeserializeSchemaAware {
595 value_type: &'static str,
596 value: String,
597 schema: Schema,
598 },
599
600 #[error("Only expected `deserialize_identifier` to be called but `{0}` was called")]
601 DeserializeIdentifier(&'static str),
602
603 #[error("Failed to write buffer bytes during flush: {0}")]
604 WriteBytes(#[source] std::io::Error),
605
606 #[error("Failed to flush inner writer during flush: {0}")]
607 FlushWriter(#[source] std::io::Error),
608
609 #[error("Failed to write marker: {0}")]
610 WriteMarker(#[source] std::io::Error),
611
612 #[error("Failed to convert JSON to string: {0}")]
613 ConvertJsonToString(#[source] serde_json::Error),
614
615 #[error("failed to convert avro float to json: {0}")]
617 ConvertF64ToJson(f64),
618
619 #[error("Unresolved schema reference: {0}")]
621 SchemaResolutionError(Name),
622
623 #[error("The file metadata is already flushed.")]
624 FileHeaderAlreadyWritten,
625
626 #[error("Metadata keys starting with 'avro.' are reserved for internal usage: {0}.")]
627 InvalidMetadataKey(String),
628
629 #[error("Two named schema defined for same fullname: {0}.")]
631 AmbiguousSchemaDefinition(Name),
632
633 #[error("Signed decimal bytes length {0} not equal to fixed schema size {1}.")]
634 EncodeDecimalAsFixedError(usize, usize),
635
636 #[error("There is no entry for '{0}' in the lookup table: {1}.")]
637 NoEntryInLookupTable(String, String),
638
639 #[error("Can only encode value type {value_kind:?} as one of {supported_schema:?}")]
640 EncodeValueAsSchemaError {
641 value_kind: ValueKind,
642 supported_schema: Vec<SchemaKind>,
643 },
644 #[error("Internal buffer not drained properly. Re-initialize the single object writer struct!")]
645 IllegalSingleObjectWriterState,
646
647 #[error("Codec '{0}' is not supported/enabled")]
648 CodecNotSupported(String),
649
650 #[error("Invalid Avro data! Cannot read codec type from value that is not Value::Bytes.")]
651 BadCodecMetadata,
652
653 #[error("Cannot convert a slice to Uuid: {0}")]
654 UuidFromSlice(#[source] uuid::Error),
655
656 #[error("Expected String for Map key when serializing a flattened struct")]
657 MapFieldExpectedString,
658
659 #[error("No key for value when serializing a map")]
660 MapNoKey,
661
662 #[error(
663 "The implementation of `SchemaNameValidator` is incorrect! It returned an out-of-bounds index or provided a regex that did not capture a group named `name`"
664 )]
665 InvalidSchemaNameValidatorImplementation,
666
667 #[error(
668 "Not all tuple fields were serialized, expected to serialize element at position {position} of a {total_elements}-tuple but `SerializeTuple::end()` was called"
669 )]
670 SerializeTupleMissingElements {
671 position: usize,
672 total_elements: usize,
673 },
674}
675
676#[derive(thiserror::Error, PartialEq)]
677pub enum CompatibilityError {
678 #[error(
679 "Incompatible schema types! Writer schema is '{writer_schema_type}', but reader schema is '{reader_schema_type}'"
680 )]
681 WrongType {
682 writer_schema_type: String,
683 reader_schema_type: String,
684 },
685
686 #[error("Incompatible schema types! The {schema_type} should have been {expected_type:?}")]
687 TypeExpected {
688 schema_type: String,
689 expected_type: Vec<SchemaKind>,
690 },
691
692 #[error(
693 "Incompatible schemata! Field '{0}' in reader schema does not match the type in the writer schema"
694 )]
695 FieldTypeMismatch(String, #[source] Box<CompatibilityError>),
696
697 #[error("Incompatible schemata! Field '{0}' in reader schema must have a default value")]
698 MissingDefaultValue(String),
699
700 #[error("Incompatible schemata! Reader's symbols contain none of the writer's symbols")]
701 MissingSymbols,
702
703 #[error("Incompatible schemata! All elements in union must match for both schemas")]
704 MissingUnionElements,
705
706 #[error("Incompatible schemata! At least one element in the union must match the schema")]
707 SchemaMismatchAllUnionElements,
708
709 #[error("Incompatible schemata! Size doesn't match for fixed")]
710 FixedMismatch,
711
712 #[error(
713 "Incompatible schemata! Decimal precision and/or scale don't match, reader: ({r_precision},{r_scale}), writer: ({w_precision},{w_scale})"
714 )]
715 DecimalMismatch {
716 r_precision: usize,
717 r_scale: usize,
718 w_precision: usize,
719 w_scale: usize,
720 },
721
722 #[error(
723 "Incompatible schemata! The name must be the same for both schemas. Writer's name {writer_name} and reader's name {reader_name}"
724 )]
725 NameMismatch {
726 writer_name: String,
727 reader_name: String,
728 },
729
730 #[error(
731 "Incompatible schemata! Unknown type for '{0}'. Make sure that the type is a valid one"
732 )]
733 Inconclusive(String),
734}
735
736impl serde::ser::Error for Details {
737 fn custom<T: fmt::Display>(msg: T) -> Self {
738 Details::SerializeValue(msg.to_string())
739 }
740}
741
742impl serde::de::Error for Details {
743 fn custom<T: fmt::Display>(msg: T) -> Self {
744 Details::DeserializeValue(msg.to_string())
745 }
746}
747
748impl fmt::Debug for Details {
749 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
750 let mut msg = self.to_string();
751 if let Some(e) = self.source() {
752 msg.extend([": ", &e.to_string()]);
753 }
754 write!(f, "{msg}")
755 }
756}
757
758impl fmt::Debug for CompatibilityError {
759 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
760 let mut msg = self.to_string();
761 if let Some(e) = self.source() {
762 msg.extend([": ", &e.to_string()]);
763 }
764 write!(f, "{msg}")
765 }
766}