@@ -78,6 +78,7 @@ pub struct SchemaAwareDeserializer<'s, 'r, R: Read, S: Borrow<Schema>> {
7878 /// This schema is guaranteed to not be a [`Schema::Ref`].
7979 schema : & ' s Schema ,
8080 config : Config < ' s , S > ,
81+ branch_index : Option < usize > ,
8182}
8283
8384impl < ' s , ' r , R : Read , S : Borrow < Schema > > SchemaAwareDeserializer < ' s , ' r , R , S > {
@@ -95,12 +96,14 @@ impl<'s, 'r, R: Read, S: Borrow<Schema>> SchemaAwareDeserializer<'s, 'r, R, S> {
9596 reader,
9697 schema,
9798 config,
99+ branch_index : None ,
98100 } )
99101 } else {
100102 Ok ( Self {
101103 reader,
102104 schema,
103105 config,
106+ branch_index : None ,
104107 } )
105108 }
106109 }
@@ -128,18 +131,22 @@ impl<'s, 'r, R: Read, S: Borrow<Schema>> SchemaAwareDeserializer<'s, 'r, R, S> {
128131 Ok ( self )
129132 }
130133
131- fn with_nullable_union_three_plus_variants (
132- self ,
133- ) -> ThreePlusVariantUnionDeserializer < ' s , ' r , R , S > {
134- ThreePlusVariantUnionDeserializer :: new ( self )
134+ fn with_branch_index ( mut self , branch_index : usize ) -> Self {
135+ self . branch_index = Some ( branch_index) ;
136+ self
135137 }
136138
137139 /// Read the union and create a new deserializer with the existing reader and config.
138140 ///
139141 /// This will resolve the read schema if it is a reference.
140142 fn with_union ( self , schema : & ' s UnionSchema ) -> Result < Self , Error > {
141- let index = zag_i32 ( self . reader ) ?;
142- let index = usize:: try_from ( index) . map_err ( |e| Details :: ConvertI32ToUsize ( e, index) ) ?;
143+ let index = match self . branch_index {
144+ Some ( index) => index,
145+ None => {
146+ let index = zag_i32 ( self . reader ) ?;
147+ usize:: try_from ( index) . map_err ( |e| Details :: ConvertI32ToUsize ( e, index) ) ?
148+ }
149+ } ;
143150 let variant = schema. get_variant ( index) ?;
144151 self . with_different_schema ( variant)
145152 }
@@ -540,10 +547,7 @@ impl<'de, 's, 'r, R: Read, S: Borrow<Schema>> Deserializer<'de>
540547 if union. variants ( ) . len ( ) == 2 {
541548 visitor. visit_some ( self . with_different_schema ( schema) ?)
542549 } else {
543- visitor. visit_some (
544- self . with_different_schema ( schema) ?
545- . with_nullable_union_three_plus_variants ( ) ,
546- )
550+ visitor. visit_some ( self . with_branch_index ( index) )
547551 }
548552 }
549553 } else {
@@ -719,17 +723,12 @@ impl<'de, 's, 'r, R: Read, S: Borrow<Schema>> Deserializer<'de>
719723 Schema :: Enum ( schema) => {
720724 visitor. visit_enum ( PlainEnumDeserializer :: new ( self . reader , schema) )
721725 }
722- Schema :: Union ( union) => {
723- let index = zag_i32 ( self . reader ) ?;
724- let index =
725- usize:: try_from ( index) . map_err ( |e| Details :: ConvertI32ToUsize ( e, index) ) ?;
726- let schema = union. get_variant ( index) ?;
727- visitor. visit_enum ( UnionEnumDeserializer :: new (
728- self . reader ,
729- schema,
730- self . config ,
731- ) ?)
732- }
726+ Schema :: Union ( union) => visitor. visit_enum ( UnionEnumDeserializer :: new (
727+ self . reader ,
728+ union,
729+ self . config ,
730+ self . branch_index ,
731+ ) ) ,
733732 _ => Err ( self . error ( "enum" , "Expected Schema::Enum | Schema::Union" ) ) ,
734733 }
735734 }
@@ -757,88 +756,6 @@ impl<'de, 's, 'r, R: Read, S: Borrow<Schema>> Deserializer<'de>
757756 }
758757}
759758
760- struct ThreePlusVariantUnionDeserializer < ' s , ' r , R : Read , S : Borrow < Schema > > {
761- inner : SchemaAwareDeserializer < ' s , ' r , R , S > ,
762- }
763-
764- impl < ' s , ' r , R : Read , S : Borrow < Schema > > ThreePlusVariantUnionDeserializer < ' s , ' r , R , S > {
765- fn new ( inner : SchemaAwareDeserializer < ' s , ' r , R , S > ) -> Self {
766- Self { inner }
767- }
768- }
769-
770- macro_rules! forward_to_inner_deserializer {
771- ( $( $method: ident( $( $arg: ident: $arg_ty: ty) ,* ) ; ) * ) => {
772- $(
773- fn $method<V >( self , $( $arg: $arg_ty, ) * visitor: V ) -> Result <V :: Value , Self :: Error >
774- where
775- V : Visitor <' de>,
776- {
777- self . inner. $method( $( $arg, ) * visitor)
778- }
779- ) *
780- } ;
781- }
782-
783- impl < ' de , ' s , ' r , R : Read , S : Borrow < Schema > > Deserializer < ' de >
784- for ThreePlusVariantUnionDeserializer < ' s , ' r , R , S >
785- {
786- type Error = Error ;
787-
788- fn deserialize_enum < V > (
789- self ,
790- _name : & ' static str ,
791- _variants : & ' static [ & ' static str ] ,
792- visitor : V ,
793- ) -> Result < V :: Value , Self :: Error >
794- where
795- V : Visitor < ' de > ,
796- {
797- visitor. visit_enum ( UnionEnumDeserializer :: new (
798- self . inner . reader ,
799- self . inner . schema ,
800- self . inner . config ,
801- ) ?)
802- }
803-
804- fn is_human_readable ( & self ) -> bool {
805- self . inner . config . human_readable
806- }
807-
808- forward_to_inner_deserializer ! {
809- deserialize_any( ) ;
810- deserialize_bool( ) ;
811- deserialize_i8( ) ;
812- deserialize_i16( ) ;
813- deserialize_i32( ) ;
814- deserialize_i64( ) ;
815- deserialize_i128( ) ;
816- deserialize_u8( ) ;
817- deserialize_u16( ) ;
818- deserialize_u32( ) ;
819- deserialize_u64( ) ;
820- deserialize_u128( ) ;
821- deserialize_f32( ) ;
822- deserialize_f64( ) ;
823- deserialize_char( ) ;
824- deserialize_str( ) ;
825- deserialize_string( ) ;
826- deserialize_bytes( ) ;
827- deserialize_byte_buf( ) ;
828- deserialize_option( ) ;
829- deserialize_unit( ) ;
830- deserialize_seq( ) ;
831- deserialize_map( ) ;
832- deserialize_identifier( ) ;
833- deserialize_ignored_any( ) ;
834- deserialize_unit_struct( name: & ' static str ) ;
835- deserialize_newtype_struct( name: & ' static str ) ;
836- deserialize_tuple( len: usize ) ;
837- deserialize_tuple_struct( name: & ' static str , len: usize ) ;
838- deserialize_struct( name: & ' static str , fields: & ' static [ & ' static str ] ) ;
839- }
840- }
841-
842759#[ cfg( test) ]
843760mod tests {
844761 use std:: fmt:: Debug ;
0 commit comments