@@ -227,7 +227,6 @@ pub comptime fn generate_deserialize_from_fields(
227
227
/// # Parameters
228
228
/// - `name`: The base identifier (e.g., `self`, `some_var`).
229
229
/// - `typ`: The type being serialized (e.g., a custom struct, array, or primitive type).
230
- /// - `omit`: A list of field names (as `Quoted`) to be excluded from the serialized output.
231
230
/// - `should_pack`: A boolean indicating whether the type should be packed.
232
231
///
233
232
/// # Returns
@@ -248,7 +247,7 @@ pub comptime fn generate_deserialize_from_fields(
248
247
///
249
248
/// Serializing the struct:
250
249
/// ```rust
251
- /// generate_serialize_to_fields(quote { my_mock_struct }, MockStruct, &[], false)
250
+ /// generate_serialize_to_fields(quote { my_mock_struct }, MockStruct, false)
252
251
/// // Returns:
253
252
/// // ([`my_mock_struct.a`, `my_mock_struct.b`], [])
254
253
/// ```
@@ -264,29 +263,29 @@ pub comptime fn generate_deserialize_from_fields(
264
263
///
265
264
/// Serialization output:
266
265
/// ```rust
267
- /// generate_serialize_to_fields(quote { self }, NestedStruct, &[], false)
266
+ /// generate_serialize_to_fields(quote { self }, NestedStruct, false)
268
267
/// // Returns:
269
268
/// // ([`self.m1.a`, `self.m1.b`, `self.m2.a`, `self.m2.b`], [])
270
269
/// ```
271
270
///
272
271
/// ## Array
273
272
/// For an array type:
274
273
/// ```rust
275
- /// generate_serialize_to_fields(quote { my_array }, [Field; 3], &[], false)
274
+ /// generate_serialize_to_fields(quote { my_array }, [Field; 3], false)
276
275
/// // Returns:
277
276
/// // ([`my_array[0]`, `my_array[1]`, `my_array[2]`], [])
278
277
/// ```
279
278
///
280
279
/// ## String
281
280
/// For a string field, where each character is serialized as a `Field`:
282
281
/// ```rust
283
- /// generate_serialize_to_fields(quote { my_string }, StringType, &[], false)
282
+ /// generate_serialize_to_fields(quote { my_string }, StringType, false)
284
283
/// // Returns:
285
284
/// // ([`my_string_as_bytes[0] as Field`, `my_string_as_bytes[1] as Field`, ...],
286
285
/// // [`let my_string_as_bytes = my_string.as_bytes()`])
287
286
/// ```
288
287
///
289
- /// ## Nested Struct with Omitted Field and packing enabled
288
+ /// ## Nested Struct with packing enabled
290
289
/// - u128 has a `Packable` implementation hence it will be packed.
291
290
///
292
291
/// For a more complex struct:
@@ -297,128 +296,109 @@ pub comptime fn generate_deserialize_from_fields(
297
296
/// }
298
297
/// ```
299
298
///
300
- /// Serializing while omitting `value2`:
301
- /// ```rust
302
- /// generate_serialize_to_fields(quote { self }, MyStruct, &[quote { self.value2 }], true)
303
- /// // Returns:
304
- /// // ([`value_packed[0]`], [`let value_packed = self.value.pack()`])
305
- /// ```
306
- ///
307
299
/// # Panics
308
300
/// - If the type is unsupported for serialization.
309
301
/// - If the provided `typ` contains invalid constants or incompatible structures.
310
302
pub comptime fn generate_serialize_to_fields (
311
303
name : Quoted ,
312
304
typ : Type ,
313
- omit : [Quoted ],
314
305
should_pack : bool ,
315
306
) -> ([Quoted ], [Quoted ]) {
316
307
let mut fields = &[];
317
308
let mut aux_vars = &[];
318
309
319
- // Proceed if none of the omit rules omits this name
320
- if !omit .any (|to_omit | to_omit == name ) {
321
- // If the type implements `Packable`, its length will be assigned to the `maybe_packed_len_typ` variable.
322
- let maybe_packed_len_typ = std::meta::typ:: fresh_type_variable ();
323
- let packable_constraint =
324
- quote { crate ::traits::Packable <$maybe_packed_len_typ > }.as_trait_constraint ();
325
-
326
- if (should_pack & typ .implements (packable_constraint )) {
327
- // Packing is enabled and the given type implements the `Packable` trait so we call the `pack()`
328
- // method, add the resulting field array to `aux_vars` and each field to `fields`.
329
- let packed_len = maybe_packed_len_typ .as_constant ().unwrap ();
330
-
331
- // We collapse the name to a one that gets tokenized as a single token (e.g. "self.value" -> "self_value").
332
- let name_at_one_token = collapse_to_one_token (name );
333
- let packed_struct_name = f"{ name_at_one_token} _aux_var" .quoted_contents ();
334
-
335
- // We add the individual fields to the fields array
336
- let pack_method = get_trait_impl_method (
337
- typ ,
338
- quote { crate ::traits::Packable <$packed_len > },
339
- quote { pack },
340
- );
341
- let packed_struct = quote { let $packed_struct_name = $pack_method ($name ) };
342
- for i in 0 ..packed_len {
343
- fields = fields .push_back (quote { $packed_struct_name [$i ] });
344
- }
310
+ // If the type implements `Packable`, its length will be assigned to the `maybe_packed_len_typ` variable.
311
+ let maybe_packed_len_typ = std::meta::typ:: fresh_type_variable ();
312
+ let packable_constraint =
313
+ quote { crate ::traits::Packable <$maybe_packed_len_typ > }.as_trait_constraint ();
345
314
346
- // We add the new auxiliary variable to the aux_vars array
347
- aux_vars = aux_vars .push_back (packed_struct );
348
- } else if typ .is_field () {
349
- // For field we just add the value to fields
350
- fields = fields .push_back (name );
351
- } else if typ .as_integer ().is_some () | typ .is_bool () {
352
- // For integer and bool we just cast to Field and add the value to fields
353
- fields = fields .push_back (quote { $name as Field });
354
- } else if typ .as_data_type ().is_some () {
355
- // For struct we pref
356
- let nested_struct = typ .as_data_type ().unwrap ();
357
- let params = nested_struct .0 .fields (nested_struct .1 );
358
- let struct_flattened = params .map (|(param_name , param_type ): (Quoted , Type )| {
359
- let maybe_prefixed_name = if name == quote {} {
360
- // Triggered when the param name is of a value available in the current scope (e.g. a function
361
- // argument) --> then we don't prefix the name with anything.
362
- param_name
363
- } else {
364
- // Triggered when we want to prefix the param name with the `name` from function input. This
365
- // can typically be `self` when implementing a method on a struct.
366
- quote { $name .$param_name }
367
- };
368
- generate_serialize_to_fields (
369
- quote {$maybe_prefixed_name },
370
- param_type ,
371
- omit ,
372
- should_pack ,
373
- )
374
- });
375
- let struct_flattened_fields = struct_flattened .fold (
376
- &[],
377
- |acc : [Quoted ], (fields , _ ): (_ , [Quoted ])| acc .append (fields ),
378
- );
379
- let struct_flattened_aux_vars = struct_flattened .fold (
380
- &[],
381
- |acc : [Quoted ], (_ , aux_vars ): ([Quoted ], _ )| acc .append (aux_vars ),
382
- );
383
- fields = fields .append (struct_flattened_fields );
384
- aux_vars = aux_vars .append (struct_flattened_aux_vars );
385
- } else if typ .as_array ().is_some () {
386
- // For array we recursively call `generate_serialize_to_fields(...)` for each element
387
- let (element_type , array_len ) = typ .as_array ().unwrap ();
388
- let array_len = array_len .as_constant ().unwrap ();
389
- for i in 0 ..array_len {
390
- let (element_fields , element_aux_vars ) = generate_serialize_to_fields (
391
- quote { $name [$i ] },
392
- element_type ,
393
- omit ,
394
- should_pack ,
395
- );
396
- fields = fields .append (element_fields );
397
- aux_vars = aux_vars .append (element_aux_vars );
398
- }
399
- } else if typ .as_str ().is_some () {
400
- // For string we convert the value to bytes, we store the `as_bytes` in an auxiliary variables and
401
- // then we add each byte to fields as a Field
402
- let length_type = typ .as_str ().unwrap ();
403
- let str_len = length_type .as_constant ().unwrap ();
404
- let as_member = name .as_expr ().unwrap ().as_member_access ();
405
- let var_name = if as_member .is_some () {
406
- as_member .unwrap ().1
315
+ if (should_pack & typ .implements (packable_constraint )) {
316
+ // Packing is enabled and the given type implements the `Packable` trait so we call the `pack()`
317
+ // method, add the resulting field array to `aux_vars` and each field to `fields`.
318
+ let packed_len = maybe_packed_len_typ .as_constant ().unwrap ();
319
+
320
+ // We collapse the name to a one that gets tokenized as a single token (e.g. "self.value" -> "self_value").
321
+ let name_at_one_token = collapse_to_one_token (name );
322
+ let packed_struct_name = f"{ name_at_one_token} _aux_var" .quoted_contents ();
323
+
324
+ // We add the individual fields to the fields array
325
+ let pack_method = get_trait_impl_method (
326
+ typ ,
327
+ quote { crate ::traits::Packable <$packed_len > },
328
+ quote { pack },
329
+ );
330
+ let packed_struct = quote { let $packed_struct_name = $pack_method ($name ) };
331
+ for i in 0 ..packed_len {
332
+ fields = fields .push_back (quote { $packed_struct_name [$i ] });
333
+ }
334
+
335
+ // We add the new auxiliary variable to the aux_vars array
336
+ aux_vars = aux_vars .push_back (packed_struct );
337
+ } else if typ .is_field () {
338
+ // For field we just add the value to fields
339
+ fields = fields .push_back (name );
340
+ } else if typ .as_integer ().is_some () | typ .is_bool () {
341
+ // For integer and bool we just cast to Field and add the value to fields
342
+ fields = fields .push_back (quote { $name as Field });
343
+ } else if typ .as_data_type ().is_some () {
344
+ // For struct we pref
345
+ let nested_struct = typ .as_data_type ().unwrap ();
346
+ let params = nested_struct .0 .fields (nested_struct .1 );
347
+ let struct_flattened = params .map (|(param_name , param_type ): (Quoted , Type )| {
348
+ let maybe_prefixed_name = if name == quote {} {
349
+ // Triggered when the param name is of a value available in the current scope (e.g. a function
350
+ // argument) --> then we don't prefix the name with anything.
351
+ param_name
407
352
} else {
408
- name
353
+ // Triggered when we want to prefix the param name with the `name` from function input. This
354
+ // can typically be `self` when implementing a method on a struct.
355
+ quote { $name .$param_name }
409
356
};
410
- let as_bytes_name = f"{ var_name} _as_bytes" .quoted_contents ();
411
- let as_bytes = quote { let $as_bytes_name = $name .as_bytes () };
412
- for i in 0 ..str_len {
413
- fields = fields .push_back (quote { $as_bytes_name [$i ] as Field });
414
- }
415
- aux_vars = aux_vars .push_back (as_bytes );
357
+ generate_serialize_to_fields (quote {$maybe_prefixed_name }, param_type , should_pack )
358
+ });
359
+ let struct_flattened_fields = struct_flattened .fold (
360
+ &[],
361
+ |acc : [Quoted ], (fields , _ ): (_ , [Quoted ])| acc .append (fields ),
362
+ );
363
+ let struct_flattened_aux_vars = struct_flattened .fold (
364
+ &[],
365
+ |acc : [Quoted ], (_ , aux_vars ): ([Quoted ], _ )| acc .append (aux_vars ),
366
+ );
367
+ fields = fields .append (struct_flattened_fields );
368
+ aux_vars = aux_vars .append (struct_flattened_aux_vars );
369
+ } else if typ .as_array ().is_some () {
370
+ // For array we recursively call `generate_serialize_to_fields(...)` for each element
371
+ let (element_type , array_len ) = typ .as_array ().unwrap ();
372
+ let array_len = array_len .as_constant ().unwrap ();
373
+ for i in 0 ..array_len {
374
+ let (element_fields , element_aux_vars ) =
375
+ generate_serialize_to_fields (quote { $name [$i ] }, element_type , should_pack );
376
+ fields = fields .append (element_fields );
377
+ aux_vars = aux_vars .append (element_aux_vars );
378
+ }
379
+ } else if typ .as_str ().is_some () {
380
+ // For string we convert the value to bytes, we store the `as_bytes` in an auxiliary variables and
381
+ // then we add each byte to fields as a Field
382
+ let length_type = typ .as_str ().unwrap ();
383
+ let str_len = length_type .as_constant ().unwrap ();
384
+ let as_member = name .as_expr ().unwrap ().as_member_access ();
385
+ let var_name = if as_member .is_some () {
386
+ as_member .unwrap ().1
416
387
} else {
417
- panic (
418
- f"Unsupported type for serialization of argument { name} and type { typ} " ,
419
- )
388
+ name
389
+ };
390
+ let as_bytes_name = f"{ var_name} _as_bytes" .quoted_contents ();
391
+ let as_bytes = quote { let $as_bytes_name = $name .as_bytes () };
392
+ for i in 0 ..str_len {
393
+ fields = fields .push_back (quote { $as_bytes_name [$i ] as Field });
420
394
}
395
+ aux_vars = aux_vars .push_back (as_bytes );
396
+ } else {
397
+ panic (
398
+ f"Unsupported type for serialization of argument { name} and type { typ} " ,
399
+ )
421
400
}
401
+
422
402
(fields , aux_vars )
423
403
}
424
404
@@ -441,7 +421,7 @@ comptime fn collapse_to_one_token(q: Quoted) -> Quoted {
441
421
442
422
pub (crate ) comptime fn derive_serialize (s : TypeDefinition ) -> Quoted {
443
423
let typ = s .as_type ();
444
- let (fields , aux_vars ) = generate_serialize_to_fields (quote { self }, typ , &[], false );
424
+ let (fields , aux_vars ) = generate_serialize_to_fields (quote { self }, typ , false );
445
425
let aux_vars_for_serialization = if aux_vars .len () > 0 {
446
426
let joint = aux_vars .join (quote {;});
447
427
quote { $joint ; }
@@ -463,7 +443,7 @@ pub(crate) comptime fn derive_serialize(s: TypeDefinition) -> Quoted {
463
443
464
444
pub (crate ) comptime fn derive_deserialize (s : TypeDefinition ) -> Quoted {
465
445
let typ = s .as_type ();
466
- let (fields , _ ) = generate_serialize_to_fields (quote { self }, typ , &[], false );
446
+ let (fields , _ ) = generate_serialize_to_fields (quote { self }, typ , false );
467
447
let serialized_len = fields .len ();
468
448
let (deserialized , _ ) =
469
449
generate_deserialize_from_fields (quote { self }, typ , quote { serialized }, 0 , false );
@@ -485,8 +465,7 @@ pub comptime fn derive_packable_and_get_packed_len(s: TypeDefinition) -> (Quoted
485
465
let packing_enabled = true ;
486
466
487
467
let typ = s .as_type ();
488
- let (fields , aux_vars ) =
489
- generate_serialize_to_fields (quote { self }, typ , &[], packing_enabled );
468
+ let (fields , aux_vars ) = generate_serialize_to_fields (quote { self }, typ , packing_enabled );
490
469
let aux_vars_for_packing = if aux_vars .len () > 0 {
491
470
let joint = aux_vars .join (quote {;});
492
471
quote { $joint ; }
0 commit comments