@@ -8,7 +8,7 @@ use crate::{
8
8
SumValue , WithTypespace , F32 , F64 ,
9
9
} ;
10
10
use crate :: { i256, u256} ;
11
- use core:: { marker:: PhantomData , ops:: Bound } ;
11
+ use core:: { iter , marker:: PhantomData , ops:: Bound } ;
12
12
use smallvec:: SmallVec ;
13
13
use spacetimedb_primitives:: { ColId , ColList } ;
14
14
use std:: { borrow:: Cow , rc:: Rc , sync:: Arc } ;
@@ -52,31 +52,103 @@ impl_prim! {
52
52
( f32 , deserialize_f32) ( f64 , deserialize_f64)
53
53
}
54
54
55
- impl_deserialize ! ( [ ] ( ) , de => de. deserialize_product( UnitVisitor ) ) ;
55
+ struct TupleVisitor < A > ( PhantomData < A > ) ;
56
+ #[ derive( Copy , Clone ) ]
57
+ struct TupleNameVisitorMax ( usize ) ;
56
58
57
- /// The `UnitVisitor` looks for a unit product.
58
- /// That is, it consumes nothing from the input.
59
- struct UnitVisitor ;
60
- impl < ' de > ProductVisitor < ' de > for UnitVisitor {
61
- type Output = ( ) ;
59
+ impl FieldNameVisitor < ' _ > for TupleNameVisitorMax {
60
+ // The index of the field name.
61
+ type Output = usize ;
62
62
63
- fn product_name ( & self ) -> Option < & str > {
64
- None
63
+ fn field_names ( & self ) -> impl ' _ + Iterator < Item = Option < & str > > {
64
+ iter :: repeat_n ( None , self . 0 )
65
65
}
66
66
67
- fn product_len ( & self ) -> usize {
68
- 0
67
+ fn kind ( & self ) -> ProductKind {
68
+ ProductKind :: Normal
69
69
}
70
70
71
- fn visit_seq_product < A : SeqProductAccess < ' de > > ( self , _prod : A ) -> Result < Self :: Output , A :: Error > {
72
- Ok ( ( ) )
71
+ fn visit < E : Error > ( self , name : & str ) -> Result < Self :: Output , E > {
72
+ let err = || Error :: unknown_field_name ( name, & self ) ;
73
+ // Convert `name` to an index.
74
+ let Ok ( index) = name. parse ( ) else {
75
+ return Err ( err ( ) ) ;
76
+ } ;
77
+ // Confirm that the index exists or error.
78
+ if index < self . 0 {
79
+ Ok ( index)
80
+ } else {
81
+ Err ( err ( ) )
82
+ }
73
83
}
74
84
75
- fn visit_named_product < A : super :: NamedProductAccess < ' de > > ( self , _prod : A ) -> Result < Self :: Output , A :: Error > {
76
- Ok ( ( ) )
85
+ fn visit_seq ( self , index : usize ) -> Self :: Output {
86
+ // Assert that the index exists.
87
+ assert ! ( index < self . 0 ) ;
88
+ index
77
89
}
78
90
}
79
91
92
+ macro_rules! impl_deserialize_tuple {
93
+ ( $( $ty_name: ident => $const_val: literal) ,* ) => {
94
+ impl <' de, $( $ty_name: Deserialize <' de>) ,* > ProductVisitor <' de> for TupleVisitor <( $( $ty_name, ) * ) > {
95
+ type Output = ( $( $ty_name, ) * ) ;
96
+ fn product_name( & self ) -> Option <& str > { None }
97
+ fn product_len( & self ) -> usize { crate :: count!( $( $ty_name) * ) }
98
+ fn visit_seq_product<A : SeqProductAccess <' de>>( self , mut _prod: A ) -> Result <Self :: Output , A :: Error > {
99
+ $(
100
+ #[ allow( non_snake_case) ]
101
+ let $ty_name = _prod
102
+ . next_element( ) ?
103
+ . ok_or_else( || Error :: invalid_product_length( $const_val, & self ) ) ?;
104
+ ) *
105
+
106
+ Ok ( ( $( $ty_name, ) * ) )
107
+ }
108
+ fn visit_named_product<A : super :: NamedProductAccess <' de>>( self , mut prod: A ) -> Result <Self :: Output , A :: Error > {
109
+ $(
110
+ #[ allow( non_snake_case) ]
111
+ let mut $ty_name = None ;
112
+ ) *
113
+
114
+ let visit = TupleNameVisitorMax ( self . product_len( ) ) ;
115
+ while let Some ( index) = prod. get_field_ident( visit) ? {
116
+ match index {
117
+ $( $const_val => {
118
+ if $ty_name. is_some( ) {
119
+ return Err ( A :: Error :: duplicate_field( $const_val, None , & self ) )
120
+ }
121
+ $ty_name = Some ( prod. get_field_value( ) ?) ;
122
+ } ) *
123
+ index => return Err ( Error :: invalid_product_length( index, & self ) ) ,
124
+ }
125
+ }
126
+ Ok ( ( $(
127
+ $ty_name. ok_or_else( || A :: Error :: missing_field( $const_val, None , & self ) ) ?,
128
+ ) * ) )
129
+ }
130
+ }
131
+
132
+ impl_deserialize!( [ $( $ty_name: Deserialize <' de>) ,* ] ( $( $ty_name, ) * ) , de => {
133
+ de. deserialize_product( TupleVisitor :: <( $( $ty_name, ) * ) >( PhantomData ) )
134
+ } ) ;
135
+ } ;
136
+ }
137
+
138
+ impl_deserialize_tuple ! ( ) ;
139
+ impl_deserialize_tuple ! ( T0 => 0 ) ;
140
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 ) ;
141
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 ) ;
142
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 ) ;
143
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 ) ;
144
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 , T5 => 5 ) ;
145
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 , T5 => 5 , T6 => 6 ) ;
146
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 , T5 => 5 , T6 => 6 , T7 => 7 ) ;
147
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 , T5 => 5 , T6 => 6 , T7 => 7 , T8 => 8 ) ;
148
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 , T5 => 5 , T6 => 6 , T7 => 7 , T8 => 8 , T9 => 9 ) ;
149
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 , T5 => 5 , T6 => 6 , T7 => 7 , T8 => 8 , T9 => 9 , T10 => 10 ) ;
150
+ impl_deserialize_tuple ! ( T0 => 0 , T1 => 1 , T2 => 2 , T3 => 3 , T4 => 4 , T5 => 5 , T6 => 6 , T7 => 7 , T8 => 8 , T9 => 9 , T10 => 10 , T11 => 11 ) ;
151
+
80
152
impl < ' de > Deserialize < ' de > for u8 {
81
153
fn deserialize < D : Deserializer < ' de > > ( deserializer : D ) -> Result < Self , D :: Error > {
82
154
deserializer. deserialize_u8 ( )
@@ -705,3 +777,36 @@ impl_deserialize!([] bytes::Bytes, de => <Vec<u8>>::deserialize(de).map(Into::in
705
777
706
778
#[ cfg( feature = "bytestring" ) ]
707
779
impl_deserialize ! ( [ ] bytestring:: ByteString , de => <String >:: deserialize( de) . map( Into :: into) ) ;
780
+
781
+ #[ cfg( test) ]
782
+ mod test {
783
+ use crate :: {
784
+ algebraic_value:: { de:: ValueDeserializer , ser:: value_serialize} ,
785
+ bsatn,
786
+ serde:: SerdeWrapper ,
787
+ Deserialize , Serialize ,
788
+ } ;
789
+ use core:: fmt:: Debug ;
790
+
791
+ #[ test]
792
+ fn roundtrip_tuples_in_different_data_formats ( ) {
793
+ fn test < T : Serialize + for < ' de > Deserialize < ' de > + Eq + Debug > ( x : T ) {
794
+ let bsatn = bsatn:: to_vec ( & x) . unwrap ( ) ;
795
+ let y: T = bsatn:: from_slice ( & bsatn) . unwrap ( ) ;
796
+ assert_eq ! ( x, y) ;
797
+
798
+ let val = value_serialize ( & x) ;
799
+ let y = T :: deserialize ( ValueDeserializer :: new ( val) ) . unwrap ( ) ;
800
+ assert_eq ! ( x, y) ;
801
+
802
+ let json = serde_json:: to_string ( SerdeWrapper :: from_ref ( & x) ) . unwrap ( ) ;
803
+ let SerdeWrapper ( y) = serde_json:: from_str :: < SerdeWrapper < T > > ( & json) . unwrap ( ) ;
804
+ assert_eq ! ( x, y) ;
805
+ }
806
+
807
+ test ( ( ) ) ;
808
+ test ( ( true , ) ) ;
809
+ test ( ( 1337u64 , false ) ) ;
810
+ test ( ( ( 7331u64 , false ) , 42u32 , 24u8 ) ) ;
811
+ }
812
+ }
0 commit comments