Skip to content

Commit 8dcb71a

Browse files
committed
Refactor serialization to not need DoubleEndedIterator
1 parent 76dec98 commit 8dcb71a

File tree

1 file changed

+154
-75
lines changed

1 file changed

+154
-75
lines changed

facet-serialize/src/lib.rs

Lines changed: 154 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ use facet_core::{
1414
Def, Facet, Field, PointerType, ScalarAffinity, SequenceType, ShapeAttribute, StructKind, Type,
1515
UserType,
1616
};
17-
use facet_reflect::{HasFields, Peek, PeekListLike, PeekMap, PeekStruct, PeekTuple, ScalarType};
17+
use facet_reflect::{
18+
FieldIter, FieldsForSerializeIter, HasFields, Peek, PeekListLikeIter, PeekMapIter, ScalarType,
19+
};
1820
use log::{debug, trace};
1921

2022
mod debug_serializer;
@@ -223,22 +225,37 @@ pub trait Serializer<'shape> {
223225
// --- Iterative Serialization Logic ---
224226

225227
/// Task items for the serialization stack.
226-
#[derive(Debug)]
227228
enum SerializeTask<'mem, 'facet, 'shape> {
228229
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+
},
229253
// End markers
230254
EndObject,
231255
EndArray,
232-
EndMap,
233256
EndMapKey,
234257
EndMapValue,
235258
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>),
242259
// Field-related tasks
243260
SerializeFieldName(&'shape str),
244261
SerializeMapKey(Peek<'mem, 'facet, 'shape>),
@@ -385,10 +402,10 @@ where
385402
serializer.serialize_bytes(cpeek.get::<Vec<u8>>().unwrap())?
386403
} else {
387404
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+
});
392409
}
393410
}
394411
(Def::Array(ad), _) => {
@@ -402,29 +419,31 @@ where
402419
serializer.serialize_bytes(&bytes)?;
403420
} else {
404421
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+
});
409426
}
410427
}
411428
(Def::Slice(sd), _) => {
412429
if sd.t().is_type::<u8>() {
413430
serializer.serialize_bytes(cpeek.get::<&[u8]>().unwrap())?
414431
} else {
415432
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+
});
420437
}
421438
}
422439
(Def::Map(_), _) => {
423440
let peek_map = cpeek.into_map().unwrap();
424441
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+
});
428447
}
429448
(Def::Option(_), _) => {
430449
let opt = cpeek.into_option().unwrap();
@@ -458,9 +477,11 @@ where
458477
let fields = peek_struct.fields_for_serialize().count();
459478
debug!(" Serializing {} fields as array", fields);
460479

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+
});
464485
trace!(
465486
" Pushed TupleStructFields to stack, will handle {} fields",
466487
fields
@@ -472,9 +493,15 @@ where
472493
let fields = peek_struct.fields_for_serialize().count();
473494
debug!(" Serializing {} fields as object", fields);
474495

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+
});
478505
trace!(
479506
" Pushed ObjectFields to stack, will handle {} fields",
480507
fields
@@ -493,9 +520,10 @@ where
493520
let count = peek_tuple.len();
494521
debug!(" Tuple fields count: {}", count);
495522

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+
});
499527
trace!(
500528
" Pushed TupleFields to stack for tuple, will handle {} fields",
501529
count
@@ -508,18 +536,18 @@ where
508536
);
509537

510538
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+
});
515543
trace!(" Pushed ArrayItems to stack for tuple serialization",);
516544
} else {
517545
// Final fallback - create an empty array
518546
debug!(
519547
" Could not convert tuple to list-like either, using empty array"
520548
);
521549
serializer.start_array(Some(0))?;
522-
stack.push(SerializeTask::EndArray);
550+
serializer.end_array()?;
523551
trace!(" Warning: Tuple serialization fallback to empty array");
524552
}
525553
}
@@ -624,49 +652,103 @@ where
624652
}
625653
}
626654

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))?;
635662
}
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));
636677
}
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()))?;
642681
}
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));
643693
}
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))?;
653701
}
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));
655715
}
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))?;
661723
}
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)));
662736
}
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()))?;
669740
}
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)));
670752
}
671753

672754
// --- Field name and map key/value handling ---
@@ -691,9 +773,6 @@ where
691773
SerializeTask::EndArray => {
692774
serializer.end_array()?;
693775
}
694-
SerializeTask::EndMap => {
695-
serializer.end_map()?;
696-
}
697776
SerializeTask::EndMapKey => {
698777
serializer.end_map_key()?;
699778
}

0 commit comments

Comments
 (0)