1use std::cell::Cell;
19
20thread_local! {
21 pub(crate) static SER_BYTES_TYPE: Cell<BytesType> = const { Cell::new(BytesType::Bytes) };
26
27 pub(crate) static DE_BYTES_BORROWED: Cell<bool> = const { Cell::new(false) };
32}
33
34#[derive(Debug, Clone, Copy)]
35pub(crate) enum BytesType {
36 Bytes,
37 Fixed,
38}
39
40struct BytesTypeGuard(BytesType);
41impl BytesTypeGuard {
42 fn set(temp: BytesType) -> Self {
43 let prev = SER_BYTES_TYPE.get();
44 SER_BYTES_TYPE.set(temp);
45 Self(prev)
46 }
47}
48
49impl Drop for BytesTypeGuard {
50 fn drop(&mut self) {
51 SER_BYTES_TYPE.set(self.0);
52 }
53}
54
55struct BorrowedGuard(bool);
56impl BorrowedGuard {
57 fn set(temp: bool) -> Self {
58 let prev = DE_BYTES_BORROWED.get();
59 DE_BYTES_BORROWED.set(temp);
60 Self(prev)
61 }
62}
63
64impl Drop for BorrowedGuard {
65 fn drop(&mut self) {
66 DE_BYTES_BORROWED.set(self.0);
67 }
68}
69
70pub mod bytes {
95 use std::collections::HashSet;
96
97 use serde::{Deserializer, Serializer};
98
99 use crate::{
100 Schema,
101 schema::{Name, Namespace, RecordField},
102 };
103
104 pub fn get_schema_in_ctxt(_: &mut HashSet<Name>, _: &Namespace) -> Schema {
106 Schema::Bytes
107 }
108
109 pub fn get_record_fields_in_ctxt(
111 _: usize,
112 _: &mut HashSet<Name>,
113 _: &Namespace,
114 ) -> Option<Vec<RecordField>> {
115 None
116 }
117
118 pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
119 where
120 S: Serializer,
121 {
122 serde_bytes::serialize(bytes, serializer)
123 }
124
125 pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
126 where
127 D: Deserializer<'de>,
128 {
129 serde_bytes::deserialize(deserializer)
130 }
131}
132
133pub mod bytes_opt {
158 use serde::{Deserializer, Serializer};
159 use std::{borrow::Borrow, collections::HashSet};
160
161 use crate::{
162 Schema,
163 schema::{Name, Namespace, RecordField, UnionSchema},
164 };
165
166 pub fn get_schema_in_ctxt(_: &mut HashSet<Name>, _: &Namespace) -> Schema {
168 Schema::Union(
169 UnionSchema::new(vec![Schema::Null, Schema::Bytes]).expect("This is a valid union"),
170 )
171 }
172
173 pub fn get_record_fields_in_ctxt(
175 _: usize,
176 _: &mut HashSet<Name>,
177 _: &Namespace,
178 ) -> Option<Vec<RecordField>> {
179 None
180 }
181
182 pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error>
183 where
184 S: Serializer,
185 B: Borrow<[u8]> + serde_bytes::Serialize,
186 {
187 serde_bytes::serialize(bytes, serializer)
188 }
189
190 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
191 where
192 D: Deserializer<'de>,
193 {
194 serde_bytes::deserialize(deserializer)
195 }
196}
197
198pub mod fixed {
223 use std::collections::HashSet;
224
225 use super::BytesType;
226 use serde::{Deserializer, Serializer};
227
228 use crate::{
229 Schema,
230 schema::{FixedSchema, Name, Namespace, RecordField},
231 };
232
233 pub fn get_schema_in_ctxt<const N: usize>(
235 named_schemas: &mut HashSet<Name>,
236 enclosing_namespace: &Namespace,
237 ) -> Schema {
238 let name = Name::new(&format!("serde_avro_fixed_{N}"))
239 .expect("Name is valid")
240 .fully_qualified_name(enclosing_namespace);
241 if named_schemas.contains(&name) {
242 Schema::Ref { name }
243 } else {
244 let schema = Schema::Fixed(FixedSchema::builder().name(name.clone()).size(N).build());
245 named_schemas.insert(name);
246 schema
247 }
248 }
249
250 pub fn get_record_fields_in_ctxt(
252 _: usize,
253 _: &mut HashSet<Name>,
254 _: &Namespace,
255 ) -> Option<Vec<RecordField>> {
256 None
257 }
258
259 pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
260 where
261 S: Serializer,
262 {
263 let _guard = super::BytesTypeGuard::set(BytesType::Fixed);
264 serde_bytes::serialize(bytes, serializer)
265 }
266
267 pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<[u8; N], D::Error>
268 where
269 D: Deserializer<'de>,
270 {
271 serde_bytes::deserialize(deserializer)
272 }
273}
274
275pub mod fixed_opt {
300 use super::BytesType;
301 use serde::{Deserializer, Serializer};
302 use std::{borrow::Borrow, collections::HashSet};
303
304 use crate::{
305 Schema,
306 schema::{Name, Namespace, RecordField, UnionSchema},
307 };
308
309 pub fn get_schema_in_ctxt<const N: usize>(
311 named_schemas: &mut HashSet<Name>,
312 enclosing_namespace: &Namespace,
313 ) -> Schema {
314 Schema::Union(
315 UnionSchema::new(vec![
316 Schema::Null,
317 super::fixed::get_schema_in_ctxt::<N>(named_schemas, enclosing_namespace),
318 ])
319 .expect("This is a valid union"),
320 )
321 }
322
323 pub fn get_record_fields_in_ctxt(
325 _: usize,
326 _: &mut HashSet<Name>,
327 _: &Namespace,
328 ) -> Option<Vec<RecordField>> {
329 None
330 }
331
332 pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error>
333 where
334 S: Serializer,
335 B: Borrow<[u8]> + serde_bytes::Serialize,
336 {
337 let _guard = super::BytesTypeGuard::set(BytesType::Fixed);
338 serde_bytes::serialize(bytes, serializer)
339 }
340
341 pub fn deserialize<'de, D, const N: usize>(deserializer: D) -> Result<Option<[u8; N]>, D::Error>
342 where
343 D: Deserializer<'de>,
344 {
345 serde_bytes::deserialize(deserializer)
346 }
347}
348
349pub mod slice {
376 use std::collections::HashSet;
377
378 use serde::{Deserializer, Serializer};
379
380 use crate::{
381 Schema,
382 schema::{Name, Namespace, RecordField},
383 };
384
385 pub fn get_schema_in_ctxt(_: &mut HashSet<Name>, _: &Namespace) -> Schema {
387 Schema::Bytes
388 }
389
390 pub fn get_record_fields_in_ctxt(
392 _: usize,
393 _: &mut HashSet<Name>,
394 _: &Namespace,
395 ) -> Option<Vec<RecordField>> {
396 None
397 }
398
399 pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
400 where
401 S: Serializer,
402 {
403 serde_bytes::serialize(bytes, serializer)
404 }
405
406 pub fn deserialize<'de, D>(deserializer: D) -> Result<&'de [u8], D::Error>
407 where
408 D: Deserializer<'de>,
409 {
410 let _guard = super::BorrowedGuard::set(true);
411 serde_bytes::deserialize(deserializer)
412 }
413}
414
415pub mod slice_opt {
442 use serde::{Deserializer, Serializer};
443 use std::{borrow::Borrow, collections::HashSet};
444
445 use crate::{
446 Schema,
447 schema::{Name, Namespace, RecordField, UnionSchema},
448 };
449
450 pub fn get_schema_in_ctxt(_: &mut HashSet<Name>, _: &Namespace) -> Schema {
452 Schema::Union(
453 UnionSchema::new(vec![Schema::Null, Schema::Bytes]).expect("This is a valid union"),
454 )
455 }
456
457 pub fn get_record_fields_in_ctxt(
459 _: usize,
460 _: &mut HashSet<Name>,
461 _: &Namespace,
462 ) -> Option<Vec<RecordField>> {
463 None
464 }
465
466 pub fn serialize<S, B>(bytes: &Option<B>, serializer: S) -> Result<S::Ok, S::Error>
467 where
468 S: Serializer,
469 B: Borrow<[u8]> + serde_bytes::Serialize,
470 {
471 serde_bytes::serialize(&bytes, serializer)
472 }
473
474 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<&'de [u8]>, D::Error>
475 where
476 D: Deserializer<'de>,
477 {
478 let _guard = super::BorrowedGuard::set(true);
479 serde_bytes::deserialize(deserializer)
480 }
481}
482
483#[cfg(test)]
484mod tests {
485 use crate::{Schema, from_value, to_value, types::Value};
486 use serde::{Deserialize, Serialize};
487
488 #[test]
489 fn avro_3631_validate_schema_for_struct_with_byte_types() {
490 #[derive(Debug, Serialize)]
491 struct TestStructWithBytes<'a> {
492 #[serde(with = "crate::serde::bytes")]
493 vec_field: Vec<u8>,
494 #[serde(with = "crate::serde::bytes_opt")]
495 vec_field_opt: Option<Vec<u8>>,
496
497 #[serde(with = "crate::serde::fixed")]
498 fixed_field: [u8; 6],
499 #[serde(with = "crate::serde::fixed_opt")]
500 fixed_field_opt: Option<[u8; 7]>,
501
502 #[serde(with = "crate::serde::slice")]
503 slice_field: &'a [u8],
504 #[serde(with = "crate::serde::slice_opt")]
505 slice_field_opt: Option<&'a [u8]>,
506 }
507
508 let test = TestStructWithBytes {
509 vec_field: vec![2, 3, 4],
510 vec_field_opt: Some(vec![2, 3, 4]),
511 fixed_field: [1; 6],
512 fixed_field_opt: Some([1; 7]),
513 slice_field: &[1, 2, 3],
514 slice_field_opt: Some(&[1, 2, 3]),
515 };
516 let value: Value = to_value(test).unwrap();
517 let schema = Schema::parse_str(
518 r#"
519 {
520 "type": "record",
521 "name": "TestStructWithBytes",
522 "fields": [ {
523 "name": "vec_field",
524 "type": "bytes"
525 }, {
526 "name": "vec_field_opt",
527 "type": ["null", "bytes"]
528 }, {
529 "name": "fixed_field",
530 "type": {
531 "name": "ByteData",
532 "type": "fixed",
533 "size": 6
534 }
535 }, {
536 "name": "fixed_field_opt",
537 "type": ["null", {
538 "name": "ByteData2",
539 "type": "fixed",
540 "size": 7
541 } ]
542 }, {
543 "name": "slice_field",
544 "type": "bytes"
545 }, {
546 "name": "slice_field_opt",
547 "type": ["null", "bytes"]
548 } ]
549 }"#,
550 )
551 .unwrap();
552 assert!(value.validate(&schema));
553 }
554
555 #[test]
556 fn avro_3631_deserialize_value_to_struct_with_byte_types() {
557 #[derive(Debug, Deserialize, PartialEq)]
558 struct TestStructWithBytes<'a> {
559 #[serde(with = "crate::serde::bytes")]
560 vec_field: Vec<u8>,
561 #[serde(with = "crate::serde::bytes_opt")]
562 vec_field_opt: Option<Vec<u8>>,
563 #[serde(with = "crate::serde::bytes_opt")]
564 vec_field_opt2: Option<Vec<u8>>,
565
566 #[serde(with = "crate::serde::fixed")]
567 fixed_field: [u8; 6],
568 #[serde(with = "crate::serde::fixed_opt")]
569 fixed_field_opt: Option<[u8; 7]>,
570 #[serde(with = "crate::serde::fixed_opt")]
571 fixed_field_opt2: Option<[u8; 8]>,
572
573 #[serde(with = "crate::serde::slice")]
574 slice_bytes_field: &'a [u8],
575 #[serde(with = "crate::serde::slice_opt")]
576 slice_bytes_field_opt: Option<&'a [u8]>,
577 #[serde(with = "crate::serde::slice_opt")]
578 slice_bytes_field_opt2: Option<&'a [u8]>,
579
580 #[serde(with = "crate::serde::slice")]
581 slice_fixed_field: &'a [u8],
582 #[serde(with = "crate::serde::slice_opt")]
583 slice_fixed_field_opt: Option<&'a [u8]>,
584 #[serde(with = "crate::serde::slice_opt")]
585 slice_fixed_field_opt2: Option<&'a [u8]>,
586 }
587
588 let expected = TestStructWithBytes {
589 vec_field: vec![3, 33],
590 vec_field_opt: Some(vec![4, 44]),
591 vec_field_opt2: None,
592 fixed_field: [1; 6],
593 fixed_field_opt: Some([7; 7]),
594 fixed_field_opt2: None,
595 slice_bytes_field: &[1, 11, 111],
596 slice_bytes_field_opt: Some(&[5, 5, 5, 5, 5]),
597 slice_bytes_field_opt2: None,
598 slice_fixed_field: &[2, 22, 222],
599 slice_fixed_field_opt: Some(&[3, 3, 3]),
600 slice_fixed_field_opt2: None,
601 };
602
603 let value = Value::Record(vec![
604 (
605 "vec_field".to_owned(),
606 Value::Bytes(expected.vec_field.clone()),
607 ),
608 (
609 "vec_field_opt".to_owned(),
610 Value::Union(
611 1,
612 Box::new(Value::Bytes(
613 expected.vec_field_opt.as_ref().unwrap().clone(),
614 )),
615 ),
616 ),
617 (
618 "vec_field_opt2".to_owned(),
619 Value::Union(0, Box::new(Value::Null)),
620 ),
621 (
622 "fixed_field".to_owned(),
623 Value::Fixed(expected.fixed_field.len(), expected.fixed_field.to_vec()),
624 ),
625 (
626 "fixed_field_opt".to_owned(),
627 Value::Union(
628 1,
629 Box::new(Value::Fixed(
630 expected.fixed_field_opt.as_ref().unwrap().len(),
631 expected.fixed_field_opt.as_ref().unwrap().to_vec(),
632 )),
633 ),
634 ),
635 (
636 "fixed_field_opt2".to_owned(),
637 Value::Union(0, Box::new(Value::Null)),
638 ),
639 (
640 "slice_bytes_field".to_owned(),
641 Value::Bytes(expected.slice_bytes_field.to_vec()),
642 ),
643 (
644 "slice_bytes_field_opt".to_owned(),
645 Value::Union(
646 1,
647 Box::new(Value::Bytes(
648 expected.slice_bytes_field_opt.as_ref().unwrap().to_vec(),
649 )),
650 ),
651 ),
652 (
653 "slice_bytes_field_opt2".to_owned(),
654 Value::Union(0, Box::new(Value::Null)),
655 ),
656 (
657 "slice_fixed_field".to_owned(),
658 Value::Fixed(
659 expected.slice_fixed_field.len(),
660 expected.slice_fixed_field.to_vec(),
661 ),
662 ),
663 (
664 "slice_fixed_field_opt".to_owned(),
665 Value::Union(
666 1,
667 Box::new(Value::Fixed(
668 expected.slice_fixed_field_opt.as_ref().unwrap().len(),
669 expected.slice_fixed_field_opt.as_ref().unwrap().to_vec(),
670 )),
671 ),
672 ),
673 (
674 "slice_fixed_field_opt2".to_owned(),
675 Value::Union(1, Box::new(Value::Null)),
676 ),
677 ]);
678 assert_eq!(expected, from_value(&value).unwrap());
679 }
680
681 #[test]
682 fn avro_3631_serialize_struct_to_value_with_byte_types() {
683 #[derive(Debug, Serialize)]
684 struct TestStructWithBytes<'a> {
685 array_field: &'a [u8],
686 vec_field: Vec<u8>,
687
688 #[serde(with = "crate::serde::fixed")]
689 vec_field2: Vec<u8>,
690 #[serde(with = "crate::serde::fixed_opt")]
691 vec_field2_opt: Option<Vec<u8>>,
692 #[serde(with = "crate::serde::fixed_opt")]
693 vec_field2_opt2: Option<Vec<u8>>,
694
695 #[serde(with = "crate::serde::bytes")]
696 vec_field3: Vec<u8>,
697 #[serde(with = "crate::serde::bytes_opt")]
698 vec_field3_opt: Option<Vec<u8>>,
699 #[serde(with = "crate::serde::bytes_opt")]
700 vec_field3_opt2: Option<Vec<u8>>,
701
702 #[serde(with = "crate::serde::fixed")]
703 fixed_field: [u8; 6],
704 #[serde(with = "crate::serde::fixed_opt")]
705 fixed_field_opt: Option<[u8; 5]>,
706 #[serde(with = "crate::serde::fixed_opt")]
707 fixed_field_opt2: Option<[u8; 4]>,
708
709 #[serde(with = "crate::serde::fixed")]
710 fixed_field2: &'a [u8],
711 #[serde(with = "crate::serde::fixed_opt")]
712 fixed_field2_opt: Option<&'a [u8]>,
713 #[serde(with = "crate::serde::fixed_opt")]
714 fixed_field2_opt2: Option<&'a [u8]>,
715
716 #[serde(with = "crate::serde::bytes")]
717 bytes_field: &'a [u8],
718 #[serde(with = "crate::serde::bytes_opt")]
719 bytes_field_opt: Option<&'a [u8]>,
720 #[serde(with = "crate::serde::bytes_opt")]
721 bytes_field_opt2: Option<&'a [u8]>,
722
723 #[serde(with = "crate::serde::bytes")]
724 bytes_field2: [u8; 6],
725 #[serde(with = "crate::serde::bytes_opt")]
726 bytes_field2_opt: Option<[u8; 7]>,
727 #[serde(with = "crate::serde::bytes_opt")]
728 bytes_field2_opt2: Option<[u8; 8]>,
729 }
730
731 let test = TestStructWithBytes {
732 array_field: &[1, 11, 111],
733 vec_field: vec![3, 33],
734 vec_field2: vec![4, 44],
735 vec_field2_opt: Some(vec![14, 144]),
736 vec_field2_opt2: None,
737 vec_field3: vec![5, 55],
738 vec_field3_opt: Some(vec![15, 155]),
739 vec_field3_opt2: None,
740 fixed_field: [1; 6],
741 fixed_field_opt: Some([6; 5]),
742 fixed_field_opt2: None,
743 fixed_field2: &[6, 66],
744 fixed_field2_opt: Some(&[7, 77]),
745 fixed_field2_opt2: None,
746 bytes_field: &[2, 22, 222],
747 bytes_field_opt: Some(&[3, 33, 233]),
748 bytes_field_opt2: None,
749 bytes_field2: [2; 6],
750 bytes_field2_opt: Some([2; 7]),
751 bytes_field2_opt2: None,
752 };
753 let expected = Value::Record(vec![
754 (
755 "array_field".to_owned(),
756 Value::Array(
757 test.array_field
758 .iter()
759 .map(|&i| Value::Int(i as i32))
760 .collect(),
761 ),
762 ),
763 (
764 "vec_field".to_owned(),
765 Value::Array(
766 test.vec_field
767 .iter()
768 .map(|&i| Value::Int(i as i32))
769 .collect(),
770 ),
771 ),
772 (
773 "vec_field2".to_owned(),
774 Value::Fixed(test.vec_field2.len(), test.vec_field2.clone()),
775 ),
776 (
777 "vec_field2_opt".to_owned(),
778 Value::Union(
779 1,
780 Box::new(Value::Fixed(
781 test.vec_field2_opt.as_ref().unwrap().len(),
782 test.vec_field2_opt.as_ref().unwrap().to_vec(),
783 )),
784 ),
785 ),
786 (
787 "vec_field2_opt2".to_owned(),
788 Value::Union(0, Box::new(Value::Null)),
789 ),
790 (
791 "vec_field3".to_owned(),
792 Value::Bytes(test.vec_field3.clone()),
793 ),
794 (
795 "vec_field3_opt".to_owned(),
796 Value::Union(
797 1,
798 Box::new(Value::Bytes(test.vec_field3_opt.as_ref().unwrap().clone())),
799 ),
800 ),
801 (
802 "vec_field3_opt2".to_owned(),
803 Value::Union(0, Box::new(Value::Null)),
804 ),
805 (
806 "fixed_field".to_owned(),
807 Value::Fixed(test.fixed_field.len(), test.fixed_field.to_vec()),
808 ),
809 (
810 "fixed_field_opt".to_owned(),
811 Value::Union(
812 1,
813 Box::new(Value::Fixed(
814 test.fixed_field_opt.as_ref().unwrap().len(),
815 test.fixed_field_opt.as_ref().unwrap().to_vec(),
816 )),
817 ),
818 ),
819 (
820 "fixed_field_opt2".to_owned(),
821 Value::Union(0, Box::new(Value::Null)),
822 ),
823 (
824 "fixed_field2".to_owned(),
825 Value::Fixed(test.fixed_field2.len(), test.fixed_field2.to_vec()),
826 ),
827 (
828 "fixed_field2_opt".to_owned(),
829 Value::Union(
830 1,
831 Box::new(Value::Fixed(
832 test.fixed_field2_opt.as_ref().unwrap().len(),
833 test.fixed_field2_opt.as_ref().unwrap().to_vec(),
834 )),
835 ),
836 ),
837 (
838 "fixed_field2_opt2".to_owned(),
839 Value::Union(0, Box::new(Value::Null)),
840 ),
841 (
842 "bytes_field".to_owned(),
843 Value::Bytes(test.bytes_field.to_vec()),
844 ),
845 (
846 "bytes_field_opt".to_owned(),
847 Value::Union(
848 1,
849 Box::new(Value::Bytes(
850 test.bytes_field_opt.as_ref().unwrap().to_vec(),
851 )),
852 ),
853 ),
854 (
855 "bytes_field_opt2".to_owned(),
856 Value::Union(0, Box::new(Value::Null)),
857 ),
858 (
859 "bytes_field2".to_owned(),
860 Value::Bytes(test.bytes_field2.to_vec()),
861 ),
862 (
863 "bytes_field2_opt".to_owned(),
864 Value::Union(
865 1,
866 Box::new(Value::Bytes(
867 test.bytes_field2_opt.as_ref().unwrap().to_vec(),
868 )),
869 ),
870 ),
871 (
872 "bytes_field2_opt2".to_owned(),
873 Value::Union(0, Box::new(Value::Null)),
874 ),
875 ]);
876 assert_eq!(expected, to_value(test).unwrap());
877 }
878}