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