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