@@ -347,7 +347,8 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
347347 de_generics. params . insert ( 0 , de_lt_param. into ( ) ) ;
348348 let ( de_impl_generics, _, de_where_clause) = de_generics. split_for_impl ( ) ;
349349
350- let ( iter_n, iter_n2, iter_n3, iter_n4) = ( 0usize .., 0usize .., 0usize .., 0usize ..) ;
350+ let ( iter_n, iter_n2, iter_n3, iter_n4, iter_n5, iter_n6, iter_n7) =
351+ ( 0usize .., 0usize .., 0usize .., 0usize .., 0usize .., 0usize .., 0usize ..) ;
351352
352353 match & ty. data {
353354 SatsTypeData :: Product ( fields) => {
@@ -382,8 +383,10 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
382383
383384 let field_names = fields. iter ( ) . map ( |f| f. ident . unwrap ( ) ) . collect :: < Vec < _ > > ( ) ;
384385 let field_strings = fields. iter ( ) . map ( |f| f. name . as_deref ( ) . unwrap ( ) ) . collect :: < Vec < _ > > ( ) ;
385- let field_types = fields. iter ( ) . map ( |f| & f. ty ) ;
386+ let field_types = fields. iter ( ) . map ( |f| f. ty ) ;
386387 let field_types2 = field_types. clone ( ) ;
388+ let field_types3 = field_types. clone ( ) ;
389+ let field_types4 = field_types. clone ( ) ;
387390 quote ! {
388391 #[ allow( non_camel_case_types) ]
389392 #[ allow( clippy:: all) ]
@@ -396,6 +399,12 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
396399 _marker: std:: marker:: PhantomData :: <fn ( ) -> #name #ty_generics>,
397400 } )
398401 }
402+
403+ fn validate<D : #spacetimedb_lib:: de:: Deserializer <' de>>( deserializer: D ) -> Result <( ) , D :: Error > {
404+ deserializer. validate_product( __ProductVisitor {
405+ _marker: std:: marker:: PhantomData :: <fn ( ) -> #name #ty_generics>,
406+ } )
407+ }
399408 }
400409
401410 struct __ProductVisitor #impl_generics #where_clause {
@@ -419,6 +428,13 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
419428 . ok_or_else( || #spacetimedb_lib:: de:: Error :: invalid_product_length( #iter_n, & self ) ) ?, ) *
420429 } )
421430 }
431+ fn validate_seq_product<A : #spacetimedb_lib:: de:: SeqProductAccess <' de>>( self , mut tup: A ) -> Result <( ) , A :: Error > {
432+ #(
433+ tup. validate_next_element:: <#field_types2>( ) ?
434+ . ok_or_else( || #spacetimedb_lib:: de:: Error :: invalid_product_length( #iter_n2, & self ) ) ?;
435+ ) *
436+ Ok ( ( ) )
437+ }
422438 fn visit_named_product<A : #spacetimedb_lib:: de:: NamedProductAccess <' de>>( self , mut __prod: A ) -> Result <Self :: Output , A :: Error > {
423439 #( let mut #field_names = None ; ) *
424440 while let Some ( __field) = #spacetimedb_lib:: de:: NamedProductAccess :: get_field_ident( & mut __prod, Self {
@@ -427,17 +443,39 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
427443 match __field {
428444 #( __ProductFieldIdent:: #field_names => {
429445 if #field_names. is_some( ) {
430- return Err ( #spacetimedb_lib:: de:: Error :: duplicate_field( #iter_n2 , Some ( #field_strings) , & self ) )
446+ return Err ( #spacetimedb_lib:: de:: Error :: duplicate_field( #iter_n3 , Some ( #field_strings) , & self ) )
431447 }
432- #field_names = Some ( #spacetimedb_lib:: de:: NamedProductAccess :: get_field_value:: <#field_types2 >( & mut __prod) ?)
448+ #field_names = Some ( #spacetimedb_lib:: de:: NamedProductAccess :: get_field_value:: <#field_types3 >( & mut __prod) ?)
433449 } ) *
434450 }
435451 }
436452 Ok ( #name {
437453 #( #field_names:
438- #field_names. ok_or_else( || #spacetimedb_lib:: de:: Error :: missing_field( #iter_n3 , Some ( #field_strings) , & self ) ) ?, ) *
454+ #field_names. ok_or_else( || #spacetimedb_lib:: de:: Error :: missing_field( #iter_n4 , Some ( #field_strings) , & self ) ) ?, ) *
439455 } )
440456 }
457+ fn validate_named_product<A : #spacetimedb_lib:: de:: NamedProductAccess <' de>>( self , mut __prod: A ) -> Result <( ) , A :: Error > {
458+ #( let mut #field_names = false ; ) *
459+ while let Some ( __field) = #spacetimedb_lib:: de:: NamedProductAccess :: get_field_ident( & mut __prod, Self {
460+ _marker: std:: marker:: PhantomData ,
461+ } ) ? {
462+ match __field {
463+ #( __ProductFieldIdent:: #field_names => {
464+ if #field_names {
465+ return Err ( #spacetimedb_lib:: de:: Error :: duplicate_field( #iter_n5, Some ( #field_strings) , & self ) )
466+ }
467+ #spacetimedb_lib:: de:: NamedProductAccess :: validate_field_value:: <#field_types4>( & mut __prod) ?;
468+ #field_names = true ;
469+ } ) *
470+ }
471+ }
472+ #(
473+ if !#field_names {
474+ return Err ( #spacetimedb_lib:: de:: Error :: missing_field( #iter_n6, Some ( #field_strings) , & self ) ) ;
475+ }
476+ ) *
477+ Ok ( ( ) )
478+ }
441479 }
442480
443481 impl #de_impl_generics #spacetimedb_lib:: de:: FieldNameVisitor <' de> for __ProductVisitor #ty_generics #de_where_clause {
@@ -456,7 +494,7 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
456494
457495 fn visit_seq( self , index: usize ) -> Self :: Output {
458496 match index {
459- #( #iter_n4 => __ProductFieldIdent:: #field_names, ) *
497+ #( #iter_n7 => __ProductFieldIdent:: #field_names, ) *
460498 _ => core:: unreachable!( ) ,
461499 }
462500 }
@@ -488,6 +526,18 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
488526 }
489527 }
490528 } ) ;
529+ let arms_validate = variants. iter ( ) . map ( |var| {
530+ let ident = var. ident ;
531+ if let Some ( ty) = var. ty {
532+ quote ! {
533+ __Variant:: #ident => #spacetimedb_lib:: de:: VariantAccess :: validate:: <#ty>( __access) ?,
534+ }
535+ } else {
536+ quote ! {
537+ __Variant:: #ident => #spacetimedb_lib:: de:: VariantAccess :: validate:: <( ) >( __access) ?,
538+ }
539+ }
540+ } ) ;
491541 quote ! {
492542 #[ allow( clippy:: all) ]
493543 const _: ( ) = {
@@ -497,6 +547,12 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
497547 _marker: std:: marker:: PhantomData :: <fn ( ) -> #name #ty_generics>,
498548 } )
499549 }
550+
551+ fn validate<D : #spacetimedb_lib:: de:: Deserializer <' de>>( deserializer: D ) -> Result <( ) , D :: Error > {
552+ deserializer. validate_sum( __SumVisitor {
553+ _marker: std:: marker:: PhantomData :: <fn ( ) -> #name #ty_generics>,
554+ } )
555+ }
500556 }
501557
502558 struct __SumVisitor #impl_generics #where_clause {
@@ -516,6 +572,14 @@ pub(crate) fn derive_deserialize(ty: &SatsType<'_>) -> TokenStream {
516572 #( #arms) *
517573 }
518574 }
575+
576+ fn validate_sum<A : #spacetimedb_lib:: de:: SumAccess <' de>>( self , __data: A ) -> Result <( ) , A :: Error > {
577+ let ( __variant, __access) = __data. variant( self ) ?;
578+ match __variant {
579+ #( #arms_validate) *
580+ }
581+ Ok ( ( ) )
582+ }
519583 }
520584
521585 #[ allow( non_camel_case_types) ]
0 commit comments