@@ -14,7 +14,9 @@ use facet_core::{
14
14
Def , Facet , Field , PointerType , ScalarAffinity , SequenceType , ShapeAttribute , StructKind , Type ,
15
15
UserType ,
16
16
} ;
17
- use facet_reflect:: { HasFields , Peek , PeekListLike , PeekMap , PeekStruct , PeekTuple , ScalarType } ;
17
+ use facet_reflect:: {
18
+ FieldIter , FieldsForSerializeIter , HasFields , Peek , PeekListLikeIter , PeekMapIter , ScalarType ,
19
+ } ;
18
20
use log:: { debug, trace} ;
19
21
20
22
mod debug_serializer;
@@ -223,22 +225,37 @@ pub trait Serializer<'shape> {
223
225
// --- Iterative Serialization Logic ---
224
226
225
227
/// Task items for the serialization stack.
226
- #[ derive( Debug ) ]
227
228
enum SerializeTask < ' mem , ' facet , ' shape > {
228
229
Value ( Peek < ' mem , ' facet , ' shape > , Option < Field < ' shape > > ) ,
230
+ Object {
231
+ entries : FieldsForSerializeIter < ' mem , ' facet , ' shape > ,
232
+ first : bool ,
233
+ len : usize ,
234
+ } ,
235
+ Array {
236
+ items : PeekListLikeIter < ' mem , ' facet , ' shape > ,
237
+ first : bool ,
238
+ } ,
239
+ Map {
240
+ entries : PeekMapIter < ' mem , ' facet , ' shape > ,
241
+ first : bool ,
242
+ len : usize ,
243
+ } ,
244
+ TupleStruct {
245
+ items : FieldsForSerializeIter < ' mem , ' facet , ' shape > ,
246
+ first : bool ,
247
+ len : usize ,
248
+ } ,
249
+ Tuple {
250
+ items : FieldIter < ' mem , ' facet , ' shape > ,
251
+ first : bool ,
252
+ } ,
229
253
// End markers
230
254
EndObject ,
231
255
EndArray ,
232
- EndMap ,
233
256
EndMapKey ,
234
257
EndMapValue ,
235
258
EndField ,
236
- // Tasks to push sub-elements onto the stack
237
- ObjectFields ( PeekStruct < ' mem , ' facet , ' shape > ) ,
238
- ArrayItems ( PeekListLike < ' mem , ' facet , ' shape > ) ,
239
- TupleStructFields ( PeekStruct < ' mem , ' facet , ' shape > ) ,
240
- TupleFields ( PeekTuple < ' mem , ' facet , ' shape > ) ,
241
- MapEntries ( PeekMap < ' mem , ' facet , ' shape > ) ,
242
259
// Field-related tasks
243
260
SerializeFieldName ( & ' shape str ) ,
244
261
SerializeMapKey ( Peek < ' mem , ' facet , ' shape > ) ,
@@ -385,10 +402,10 @@ where
385
402
serializer. serialize_bytes ( cpeek. get :: < Vec < u8 > > ( ) . unwrap ( ) ) ?
386
403
} else {
387
404
let peek_list = cpeek. into_list_like ( ) . unwrap ( ) ;
388
- let len = peek_list . len ( ) ;
389
- serializer . start_array ( Some ( len ) ) ? ;
390
- stack . push ( SerializeTask :: EndArray ) ;
391
- stack . push ( SerializeTask :: ArrayItems ( peek_list ) ) ;
405
+ stack . push ( SerializeTask :: Array {
406
+ items : peek_list . iter ( ) ,
407
+ first : true ,
408
+ } ) ;
392
409
}
393
410
}
394
411
( Def :: Array ( ad) , _) => {
@@ -402,29 +419,31 @@ where
402
419
serializer. serialize_bytes ( & bytes) ?;
403
420
} else {
404
421
let peek_list = cpeek. into_list_like ( ) . unwrap ( ) ;
405
- let len = peek_list . len ( ) ;
406
- serializer . start_array ( Some ( len ) ) ? ;
407
- stack . push ( SerializeTask :: EndArray ) ;
408
- stack . push ( SerializeTask :: ArrayItems ( peek_list ) ) ;
422
+ stack . push ( SerializeTask :: Array {
423
+ items : peek_list . iter ( ) ,
424
+ first : true ,
425
+ } ) ;
409
426
}
410
427
}
411
428
( Def :: Slice ( sd) , _) => {
412
429
if sd. t ( ) . is_type :: < u8 > ( ) {
413
430
serializer. serialize_bytes ( cpeek. get :: < & [ u8 ] > ( ) . unwrap ( ) ) ?
414
431
} else {
415
432
let peek_list = cpeek. into_list_like ( ) . unwrap ( ) ;
416
- let len = peek_list . len ( ) ;
417
- serializer . start_array ( Some ( len ) ) ? ;
418
- stack . push ( SerializeTask :: EndArray ) ;
419
- stack . push ( SerializeTask :: ArrayItems ( peek_list ) ) ;
433
+ stack . push ( SerializeTask :: Array {
434
+ items : peek_list . iter ( ) ,
435
+ first : true ,
436
+ } ) ;
420
437
}
421
438
}
422
439
( Def :: Map ( _) , _) => {
423
440
let peek_map = cpeek. into_map ( ) . unwrap ( ) ;
424
441
let len = peek_map. len ( ) ;
425
- serializer. start_map ( Some ( len) ) ?;
426
- stack. push ( SerializeTask :: EndMap ) ;
427
- stack. push ( SerializeTask :: MapEntries ( peek_map) ) ;
442
+ stack. push ( SerializeTask :: Map {
443
+ entries : peek_map. iter ( ) ,
444
+ first : true ,
445
+ len,
446
+ } ) ;
428
447
}
429
448
( Def :: Option ( _) , _) => {
430
449
let opt = cpeek. into_option ( ) . unwrap ( ) ;
@@ -458,9 +477,11 @@ where
458
477
let fields = peek_struct. fields_for_serialize ( ) . count ( ) ;
459
478
debug ! ( " Serializing {} fields as array" , fields) ;
460
479
461
- serializer. start_array ( Some ( fields) ) ?;
462
- stack. push ( SerializeTask :: EndArray ) ;
463
- stack. push ( SerializeTask :: TupleStructFields ( peek_struct) ) ;
480
+ stack. push ( SerializeTask :: TupleStruct {
481
+ items : peek_struct. fields_for_serialize ( ) ,
482
+ first : true ,
483
+ len : fields,
484
+ } ) ;
464
485
trace ! (
465
486
" Pushed TupleStructFields to stack, will handle {} fields" ,
466
487
fields
@@ -472,9 +493,15 @@ where
472
493
let fields = peek_struct. fields_for_serialize ( ) . count ( ) ;
473
494
debug ! ( " Serializing {} fields as object" , fields) ;
474
495
475
- serializer. start_object ( Some ( fields) ) ?;
476
- stack. push ( SerializeTask :: EndObject ) ;
477
- stack. push ( SerializeTask :: ObjectFields ( peek_struct) ) ;
496
+ // FIXME
497
+ // serializer.start_object(Some(fields))?;
498
+ // stack.push(SerializeTask::EndObject);
499
+ // stack.push(SerializeTask::ObjectFields(peek_struct));
500
+ stack. push ( SerializeTask :: Object {
501
+ entries : peek_struct. fields_for_serialize ( ) ,
502
+ first : true ,
503
+ len : fields,
504
+ } ) ;
478
505
trace ! (
479
506
" Pushed ObjectFields to stack, will handle {} fields" ,
480
507
fields
@@ -493,9 +520,10 @@ where
493
520
let count = peek_tuple. len ( ) ;
494
521
debug ! ( " Tuple fields count: {}" , count) ;
495
522
496
- serializer. start_array ( Some ( count) ) ?;
497
- stack. push ( SerializeTask :: EndArray ) ;
498
- stack. push ( SerializeTask :: TupleFields ( peek_tuple) ) ;
523
+ stack. push ( SerializeTask :: Tuple {
524
+ items : peek_tuple. fields ( ) ,
525
+ first : true ,
526
+ } ) ;
499
527
trace ! (
500
528
" Pushed TupleFields to stack for tuple, will handle {} fields" ,
501
529
count
@@ -508,18 +536,18 @@ where
508
536
) ;
509
537
510
538
if let Ok ( peek_list_like) = cpeek. into_list_like ( ) {
511
- let count = peek_list_like . len ( ) ;
512
- serializer . start_array ( Some ( count ) ) ? ;
513
- stack . push ( SerializeTask :: EndArray ) ;
514
- stack . push ( SerializeTask :: ArrayItems ( peek_list_like ) ) ;
539
+ stack . push ( SerializeTask :: Array {
540
+ items : peek_list_like . iter ( ) ,
541
+ first : true ,
542
+ } ) ;
515
543
trace ! ( " Pushed ArrayItems to stack for tuple serialization" , ) ;
516
544
} else {
517
545
// Final fallback - create an empty array
518
546
debug ! (
519
547
" Could not convert tuple to list-like either, using empty array"
520
548
) ;
521
549
serializer. start_array ( Some ( 0 ) ) ?;
522
- stack . push ( SerializeTask :: EndArray ) ;
550
+ serializer . end_array ( ) ? ;
523
551
trace ! ( " Warning: Tuple serialization fallback to empty array" ) ;
524
552
}
525
553
}
@@ -624,49 +652,103 @@ where
624
652
}
625
653
}
626
654
627
- // --- Pushing sub-elements onto the stack ---
628
- SerializeTask :: ObjectFields ( peek_struct) => {
629
- // Push fields in reverse order for stack processing
630
- let fields_for_serialize = peek_struct. fields_for_serialize ( ) . collect :: < Vec < _ > > ( ) ;
631
- for ( field, field_peek) in fields_for_serialize. into_iter ( ) . rev ( ) {
632
- stack. push ( SerializeTask :: EndField ) ;
633
- stack. push ( SerializeTask :: Value ( field_peek, Some ( field) ) ) ;
634
- stack. push ( SerializeTask :: SerializeFieldName ( field. name ) ) ;
655
+ SerializeTask :: Object {
656
+ mut entries,
657
+ first,
658
+ len,
659
+ } => {
660
+ if first {
661
+ serializer. start_object ( Some ( len) ) ?;
635
662
}
663
+
664
+ let Some ( ( field, value) ) = entries. next ( ) else {
665
+ serializer. end_object ( ) ?;
666
+ continue ;
667
+ } ;
668
+
669
+ stack. push ( SerializeTask :: Object {
670
+ entries,
671
+ first : false ,
672
+ len,
673
+ } ) ;
674
+ stack. push ( SerializeTask :: EndField ) ;
675
+ stack. push ( SerializeTask :: Value ( value, Some ( field) ) ) ;
676
+ stack. push ( SerializeTask :: SerializeFieldName ( field. name ) ) ;
636
677
}
637
- SerializeTask :: TupleStructFields ( peek_struct) => {
638
- // Push fields in reverse order
639
- let fields_for_serialize = peek_struct. fields_for_serialize ( ) . collect :: < Vec < _ > > ( ) ;
640
- for ( field, field_peek) in fields_for_serialize. into_iter ( ) . rev ( ) {
641
- stack. push ( SerializeTask :: Value ( field_peek, Some ( field) ) ) ;
678
+ SerializeTask :: Array { mut items, first } => {
679
+ if first {
680
+ serializer. start_array ( Some ( items. len ( ) ) ) ?;
642
681
}
682
+
683
+ let Some ( value) = items. next ( ) else {
684
+ serializer. end_array ( ) ?;
685
+ continue ;
686
+ } ;
687
+
688
+ stack. push ( SerializeTask :: Array {
689
+ items,
690
+ first : false ,
691
+ } ) ;
692
+ stack. push ( SerializeTask :: Value ( value, None ) ) ;
643
693
}
644
- SerializeTask :: TupleFields ( peek_tuple) => {
645
- // Push fields in reverse order
646
- for ( _, field_peek) in peek_tuple. fields ( ) . rev ( ) {
647
- // Get the innermost peek value - this is essential for proper serialization
648
- // to unwrap transparent wrappers and get to the actual value
649
- let innermost_peek = field_peek. innermost_peek ( ) ;
650
-
651
- // Push the innermost peek to the stack
652
- stack. push ( SerializeTask :: Value ( innermost_peek, None ) ) ;
694
+ SerializeTask :: Map {
695
+ mut entries,
696
+ first,
697
+ len,
698
+ } => {
699
+ if first {
700
+ serializer. start_map ( Some ( len) ) ?;
653
701
}
654
- trace ! ( " Pushed {} tuple fields to stack" , peek_tuple. len( ) ) ;
702
+
703
+ let Some ( ( key, value) ) = entries. next ( ) else {
704
+ serializer. end_map ( ) ?;
705
+ continue ;
706
+ } ;
707
+
708
+ stack. push ( SerializeTask :: Map {
709
+ entries,
710
+ first : false ,
711
+ len,
712
+ } ) ;
713
+ stack. push ( SerializeTask :: SerializeMapValue ( value) ) ;
714
+ stack. push ( SerializeTask :: SerializeMapKey ( key) ) ;
655
715
}
656
- SerializeTask :: ArrayItems ( peek_list) => {
657
- // Push items in reverse order
658
- let items: Vec < _ > = peek_list. iter ( ) . collect ( ) ;
659
- for item_peek in items. into_iter ( ) . rev ( ) {
660
- stack. push ( SerializeTask :: Value ( item_peek, None ) ) ;
716
+ SerializeTask :: TupleStruct {
717
+ mut items,
718
+ first,
719
+ len,
720
+ } => {
721
+ if first {
722
+ serializer. start_array ( Some ( len) ) ?;
661
723
}
724
+
725
+ let Some ( ( field, value) ) = items. next ( ) else {
726
+ serializer. end_array ( ) ?;
727
+ continue ;
728
+ } ;
729
+
730
+ stack. push ( SerializeTask :: TupleStruct {
731
+ items,
732
+ first : false ,
733
+ len,
734
+ } ) ;
735
+ stack. push ( SerializeTask :: Value ( value, Some ( field) ) ) ;
662
736
}
663
- SerializeTask :: MapEntries ( peek_map) => {
664
- // Push entries in reverse order (key, value pairs)
665
- let entries = peek_map. iter ( ) . collect :: < Vec < _ > > ( ) ;
666
- for ( key_peek, value_peek) in entries. into_iter ( ) . rev ( ) {
667
- stack. push ( SerializeTask :: SerializeMapValue ( value_peek) ) ;
668
- stack. push ( SerializeTask :: SerializeMapKey ( key_peek) ) ;
737
+ SerializeTask :: Tuple { mut items, first } => {
738
+ if first {
739
+ serializer. start_array ( Some ( items. len ( ) ) ) ?;
669
740
}
741
+
742
+ let Some ( ( field, value) ) = items. next ( ) else {
743
+ serializer. end_array ( ) ?;
744
+ continue ;
745
+ } ;
746
+
747
+ stack. push ( SerializeTask :: Tuple {
748
+ items,
749
+ first : false ,
750
+ } ) ;
751
+ stack. push ( SerializeTask :: Value ( value, Some ( field) ) ) ;
670
752
}
671
753
672
754
// --- Field name and map key/value handling ---
@@ -691,9 +773,6 @@ where
691
773
SerializeTask :: EndArray => {
692
774
serializer. end_array ( ) ?;
693
775
}
694
- SerializeTask :: EndMap => {
695
- serializer. end_map ( ) ?;
696
- }
697
776
SerializeTask :: EndMapKey => {
698
777
serializer. end_map_key ( ) ?;
699
778
}
0 commit comments