@@ -228,14 +228,20 @@ pub(crate) comptime fn derive_deserialize(s: TypeDefinition) -> Quoted {
228228 let generics_declarations = get_generics_declarations (s );
229229 let where_deserialize_clause = get_where_trait_clause (s , quote {Deserialize });
230230
231- // The following will give us <type_of_struct_member_1 as Deserialize>::N + <type_of_struct_member_2 as Deserialize>::N + ...
232- let right_hand_side_of_definition_of_n = params
233- .map (|(_ , param_type , _ ): (Quoted , Type , Quoted )| {
234- quote {
231+ // The following will give us:
232+ // <type_of_struct_member_1 as Deserialize>::N + <type_of_struct_member_2 as Deserialize>::N + ...
233+ // (or 0 if the struct has no members)
234+ let right_hand_side_of_definition_of_n = if params .len () > 0 {
235+ params
236+ .map (|(_ , param_type , _ ): (Quoted , Type , Quoted )| {
237+ quote {
235238 <$param_type as $crate ::traits::Deserialize >::N
236239 }
237- })
238- .join (quote {+});
240+ })
241+ .join (quote {+})
242+ } else {
243+ quote {0 }
244+ };
239245
240246 // For structs containing a single member, we can enhance performance by directly deserializing the input array,
241247 // bypassing the need for loop-based array construction. While this optimization yields significant benefits in
@@ -269,11 +275,15 @@ pub(crate) comptime fn derive_deserialize(s: TypeDefinition) -> Quoted {
269275
270276 Self { $struct_members }
271277 }
272- } else {
278+ } else if params . len () == 1 {
273279 let param_name = params [0 ].0 ;
274280 quote {
275281 Self { $param_name : $crate ::traits::Deserialize ::deserialize (serialized ) }
276282 }
283+ } else {
284+ quote {
285+ Self {}
286+ }
277287 };
278288
279289 quote {
@@ -365,14 +375,20 @@ pub comptime fn derive_packable(s: TypeDefinition) -> Quoted {
365375 let generics_declarations = get_generics_declarations (s );
366376 let where_packable_clause = get_where_trait_clause (s , quote {Packable });
367377
368- // The following will give us <type_of_struct_member_1 as Packable>::N + <type_of_struct_member_2 as Packable>::N + ...
369- let right_hand_side_of_definition_of_n = params
370- .map (|(_ , param_type , _ ): (Quoted , Type , Quoted )| {
371- quote {
378+ // The following will give us:
379+ // <type_of_struct_member_1 as Packable>::N + <type_of_struct_member_2 as Packable>::N + ...
380+ // (or 0 if the struct has no members)
381+ let right_hand_side_of_definition_of_n = if params .len () > 0 {
382+ params
383+ .map (|(_ , param_type , _ ): (Quoted , Type , Quoted )| {
384+ quote {
372385 <$param_type as $crate ::traits::Packable >::N
373386 }
374- })
375- .join (quote {+});
387+ })
388+ .join (quote {+})
389+ } else {
390+ quote {0 }
391+ };
376392
377393 // For structs containing a single member, we can enhance performance by directly returning the packed member,
378394 // bypassing the need for loop-based array construction. While this optimization yields significant benefits in
@@ -404,11 +420,15 @@ pub comptime fn derive_packable(s: TypeDefinition) -> Quoted {
404420
405421 result
406422 }
407- } else {
423+ } else if params . len () == 1 {
408424 let param_name = params [0 ].0 ;
409425 quote {
410426 $crate ::traits::Packable ::pack (self .$param_name )
411427 }
428+ } else {
429+ quote {
430+ [0 ; Self ::N ]
431+ }
412432 };
413433
414434 // For structs containing a single member, we can enhance performance by directly unpacking the input array,
@@ -443,11 +463,15 @@ pub comptime fn derive_packable(s: TypeDefinition) -> Quoted {
443463 $unpacking_of_struct_members
444464 Self { $struct_members }
445465 }
446- } else {
466+ } else if params . len () == 1 {
447467 let param_name = params [0 ].0 ;
448468 quote {
449469 Self { $param_name : $crate ::traits::Packable ::unpack (packed ) }
450470 }
471+ } else {
472+ quote {
473+ Self {}
474+ }
451475 };
452476
453477 quote {
@@ -472,6 +496,9 @@ pub comptime fn derive_packable(s: TypeDefinition) -> Quoted {
472496mod test {
473497 use crate::traits:: {Deserialize , Packable , Serialize };
474498
499+ #[derive(Deserialize, Eq, Packable, Serialize)]
500+ pub struct Empty {}
501+
475502 #[derive(Deserialize, Eq, Packable, Serialize)]
476503 pub struct Smol {
477504 a : Field ,
@@ -498,6 +525,24 @@ mod test {
498525 pub length : u32 ,
499526 }
500527
528+ #[test]
529+ fn serde_on_empty () {
530+ let original = Empty {};
531+ let serialized = original .serialize ();
532+ assert_eq (serialized , [], "Serialized does not match empty array" );
533+ let deserialized = Empty ::deserialize (serialized );
534+ assert_eq (deserialized , original , "Deserialized does not match original" );
535+ }
536+
537+ #[test]
538+ fn packable_on_empty () {
539+ let original = Empty {};
540+ let packed = original .pack ();
541+ assert_eq (packed , [], "Packed does not match empty array" );
542+ let unpacked = Empty ::unpack (packed );
543+ assert_eq (unpacked , original , "Unpacked does not match original" );
544+ }
545+
501546 #[test]
502547 fn serde_on_smol () {
503548 let smol = Smol { a : 1 , b : 2 };
0 commit comments