Skip to main content

deser_core/de/
recording.rs

1use crate::State;
2use crate::de::{Deserialize, DeserializeDriver, Sink, SinkHandle};
3use crate::error::{Error, ErrorKind};
4use crate::event::{Atom, ContainerShape, Event};
5use crate::extensions::Snapshot;
6use crate::ser::{Chunk, MapEmitter, SeqEmitter, Serialize, SerializeHandle};
7use alloc::borrow::ToOwned;
8use alloc::boxed::Box;
9use alloc::vec::Vec;
10
11/// A recorded value that can be replayed into a sink later.
12///
13/// Some types cannot deserialize a value when it arrives because they first
14/// need to see data that comes later.  An example are internally tagged enums
15/// where the tag can come after the fields of the variant.  Such types record
16/// values and replay them once they know where they should go.
17///
18/// A recording captures the events of a value together with their input
19/// ranges (see [`State::input_range`]), the data attached to them (see
20/// [`State::event`]) and the values of all replayable extensions in the
21/// state (see [`State::set_replayable`]) at the time of each event.  When
22/// replaying, these values are restored for every event.  This means that
23/// information such as source locations or paths remains correct for replayed
24/// values.  Map keys are also replayed as map keys and atoms are recorded as
25/// they are (lexical atoms remain lexical), so format specific handling (like
26/// integer keys in JSON) continues to work.
27///
28/// ```
29/// use deser::de::{DeserializeDriver, Recording};
30/// use deser::{Deserialize, Event};
31///
32/// let mut recording = Recording::new();
33/// {
34///     let mut driver =
35///         DeserializeDriver::from_fn(|state| recording.recorder(state));
36///     driver.emit(Event::seq_start()).unwrap();
37///     driver.emit(1u64).unwrap();
38///     driver.emit(2u64).unwrap();
39///     driver.emit(Event::SeqEnd).unwrap();
40/// }
41///
42/// let mut out = None::<Vec<u32>>;
43/// {
44///     let mut driver_out = None::<()>;
45///     let mut driver = DeserializeDriver::new(&mut driver_out);
46///     let state = driver.state_mut();
47///     recording
48///         .replay(Deserialize::deserialize_into(&mut out, state), state)
49///         .unwrap();
50/// }
51/// assert_eq!(out, Some(vec![1, 2]));
52/// ```
53///
54/// Recordings are detached from the data they were recorded from: borrowed
55/// atoms are recorded as owned (see [`Atom::to_static`]).  This means that
56/// types which only accept borrowed data (like `&str`) cannot be
57/// deserialized from a replayed recording.  Types which can hold owned data
58/// (like `Cow<str>`) can.  (The buffering of the derive, for instance for
59/// internally tagged enums, keeps borrowed data borrowed.)
60///
61/// # Raw Values
62///
63/// Recordings implement [`Deserialize`] and [`Serialize`].  This makes them
64/// usable as raw values that capture any value without interpreting it, for
65/// instance for the content of `#[deser(other)]` enum variants.  When
66/// serialized the recorded events are emitted again, including the event
67/// data attached to them (see [`State::event`]).  This means that format
68/// specific information carried as event data (for instance CBOR tags)
69/// survives a round trip through a recording.
70///
71/// The lengths of maps and sequences are known once they are recorded.
72/// If the format did not know them (like JSON, which does not say how many
73/// elements an array has before its end) they are filled in, so they are
74/// available to serializers (see [`ContainerShape::len`]).
75///
76/// ```
77/// use deser::de::Recording;
78/// use deser::Deserialize;
79///
80/// #[derive(Deserialize)]
81/// pub struct Envelope {
82///     kind: String,
83///     payload: Recording,
84/// }
85/// ```
86#[derive(Clone, Default)]
87pub struct Recording(RecordBuf<'static>);
88
89/// A recording which keeps borrowed data borrowed.
90///
91/// This is like [`Recording`], but atoms that are delivered borrowed (see
92/// [`Sink::borrowed_atom`]) are recorded as they are and replayed or
93/// serialized borrowed, all others are recorded as owned.  Strings that
94/// the format can lend from the input are not copied, but the buffer
95/// cannot outlive the input.  The derive uses it to buffer values, which
96/// allows types that borrow to be deserialized from buffered values (for
97/// instance the fields of internally tagged enums that come before the
98/// tag).
99///
100/// Like recordings, record buffers implement [`Deserialize`] and
101/// [`Serialize`].  This makes them useful to pass values from a
102/// deserializer to a serializer, for instance to convert them from one
103/// format to another (which is what `deser-transcode` does):
104///
105/// ```
106/// use deser::de::{DeserializeDriver, RecordBuf};
107/// use deser::ser::SerializeDriver;
108/// use deser::Event;
109///
110/// let input = String::from("borrowed");
111/// let mut buf = RecordBuf::new();
112/// {
113///     let mut driver = DeserializeDriver::from_fn(|state| buf.recorder(state));
114///     driver.emit(Event::seq_start()).unwrap();
115///     driver.emit_borrowed(input.as_str()).unwrap();
116///     driver.emit(Event::SeqEnd).unwrap();
117/// }
118///
119/// let mut events = Vec::new();
120/// SerializeDriver::new(&buf)
121///     .drive(|event, _state| {
122///         events.push(event.to_static());
123///         Ok(())
124///     })
125///     .unwrap();
126/// // the length of the sequence is known once it was recorded
127/// assert_eq!(
128///     events,
129///     [
130///         Event::SeqStart(deser::ContainerShape::new().with_len(1)),
131///         "borrowed".into(),
132///         Event::SeqEnd,
133///     ]
134/// );
135/// ```
136#[derive(Clone, Default)]
137pub struct RecordBuf<'de> {
138    events: Events<'de>,
139    is_map_key: bool,
140}
141
142/// The recorded events.
143///
144/// Most recordings are a single atom (like the keys that tagged enums
145/// record until the variant is known), which is stored without an
146/// allocation.
147#[derive(Clone)]
148enum Events<'de> {
149    Inline(Option<RecordedEvent<'de>>),
150    Heap(Vec<RecordedEvent<'de>>),
151}
152
153impl Default for Events<'_> {
154    fn default() -> Self {
155        Events::Inline(None)
156    }
157}
158
159impl<'de> Events<'de> {
160    #[inline]
161    fn as_slice(&self) -> &[RecordedEvent<'de>] {
162        match self {
163            Events::Inline(None) => &[],
164            Events::Inline(Some(event)) => core::slice::from_ref(event),
165            Events::Heap(events) => events,
166        }
167    }
168
169    #[inline]
170    fn as_mut_slice(&mut self) -> &mut [RecordedEvent<'de>] {
171        match self {
172            Events::Inline(None) => &mut [],
173            Events::Inline(Some(event)) => core::slice::from_mut(event),
174            Events::Heap(events) => events,
175        }
176    }
177
178    #[inline]
179    fn push(&mut self, event: RecordedEvent<'de>) {
180        match self {
181            Events::Inline(slot @ None) => *slot = Some(event),
182            Events::Heap(events) => events.push(event),
183            Events::Inline(Some(_)) => {
184                self.reserve(CONTAINER_CAPACITY);
185                if let Events::Heap(events) = self {
186                    events.push(event);
187                }
188            }
189        }
190    }
191
192    #[inline]
193    fn clear(&mut self) {
194        match self {
195            Events::Inline(slot) => *slot = None,
196            // the capacity is kept for the next recording
197            Events::Heap(events) => events.clear(),
198        }
199    }
200
201    /// Reserves space for more events, the events are stored on the heap
202    /// from then on.
203    fn reserve(&mut self, additional: usize) {
204        match self {
205            Events::Inline(slot) => {
206                let mut events = Vec::with_capacity(additional + 1);
207                events.extend(slot.take());
208                *self = Events::Heap(events);
209            }
210            Events::Heap(events) => events.reserve(additional),
211        }
212    }
213}
214
215impl<'de> core::ops::Deref for Events<'de> {
216    type Target = [RecordedEvent<'de>];
217
218    #[inline]
219    fn deref(&self) -> &Self::Target {
220        self.as_slice()
221    }
222}
223
224impl core::fmt::Debug for Events<'_> {
225    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
226        core::fmt::Debug::fmt(self.as_slice(), f)
227    }
228}
229
230#[derive(Debug, Clone)]
231struct RecordedEvent<'de> {
232    event: Event<'de>,
233    // the atom was delivered borrowed and is replayed borrowed
234    borrowed: bool,
235    // the number of events of the value that starts with this event: 1 for
236    // atoms, the events of the container including the start and the end
237    // for closed containers (see `close`) and 0 if unknown.  This fits into
238    // the padding of the struct.
239    span: u32,
240    input_range: (usize, usize),
241    // `None` if the snapshot is empty, which it is unless there are
242    // replayable extensions or event data.  This keeps recorded events small.
243    snapshot: Option<Box<Snapshot>>,
244}
245
246impl RecordedEvent<'_> {
247    /// Restores the replayable extensions and the event data of the event.
248    fn restore(&self, state: &mut State) {
249        match self.snapshot {
250            Some(ref snapshot) => state.extensions_mut().restore(snapshot),
251            // restoring an empty snapshot only clears the event data
252            None => state.clear_event_data(),
253        }
254    }
255}
256
257// the span fits into the padding of recorded events
258#[cfg(target_pointer_width = "64")]
259const _: () = assert!(core::mem::size_of::<RecordedEvent<'static>>() == 64);
260
261// recordings are stored in sinks, they must not prevent them from moving
262// between threads.
263const _: () = {
264    const fn assert_send<T: Send>() {}
265    assert_send::<Recording>();
266    assert_send::<RecordBuf<'static>>();
267};
268
269impl core::fmt::Debug for Recording {
270    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
271        f.debug_struct("Recording")
272            .field("events", &self.0.events)
273            .field("is_map_key", &self.0.is_map_key)
274            .finish()
275    }
276}
277
278impl core::fmt::Debug for RecordBuf<'_> {
279    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
280        f.debug_struct("RecordBuf")
281            .field("events", &self.events)
282            .field("is_map_key", &self.is_map_key)
283            .finish()
284    }
285}
286
287/// Where a recorder records to.
288///
289/// Recordings keep owned data only, record buffers keep borrowed data.
290trait Target<'de>: Send {
291    /// Records an event.
292    fn push(&mut self, is_root: bool, event: Event<'static>, state: &State);
293
294    /// Records an atom that was delivered borrowed.
295    fn push_borrowed(&mut self, is_root: bool, atom: Atom<'de>, state: &State);
296
297    fn is_empty(&self) -> bool;
298
299    /// Returns the number of recorded events.
300    fn len(&self) -> usize;
301
302    /// Closes the container starting at the given event after its end was
303    /// recorded (see [`close`]).
304    fn close(&mut self, start: usize);
305
306    /// Reserves space for the events of a container.
307    fn reserve(&mut self);
308}
309
310/// The number of events reserved for a recorded container.
311const CONTAINER_CAPACITY: usize = 16;
312
313impl<'de> Target<'de> for RecordBuf<'de> {
314    fn push(&mut self, is_root: bool, event: Event<'static>, state: &State) {
315        record(self, is_root, event, false, state);
316    }
317
318    fn push_borrowed(&mut self, is_root: bool, atom: Atom<'de>, state: &State) {
319        record(self, is_root, Event::Atom(atom), true, state);
320    }
321
322    fn is_empty(&self) -> bool {
323        self.events.is_empty()
324    }
325
326    fn len(&self) -> usize {
327        self.events.len()
328    }
329
330    fn close(&mut self, start: usize) {
331        close(self.events.as_mut_slice(), start);
332    }
333
334    fn reserve(&mut self) {
335        self.events.reserve(CONTAINER_CAPACITY);
336    }
337}
338
339impl<'de> Target<'de> for Recording {
340    fn push(&mut self, is_root: bool, event: Event<'static>, state: &State) {
341        record(&mut self.0, is_root, event, false, state);
342    }
343
344    fn push_borrowed(&mut self, is_root: bool, atom: Atom<'de>, state: &State) {
345        let event = Event::Atom(atom.to_static());
346        record(&mut self.0, is_root, event, false, state);
347    }
348
349    fn is_empty(&self) -> bool {
350        self.0.events.is_empty()
351    }
352
353    fn len(&self) -> usize {
354        self.0.events.len()
355    }
356
357    fn close(&mut self, start: usize) {
358        close(self.0.events.as_mut_slice(), start);
359    }
360
361    fn reserve(&mut self) {
362        self.0.events.reserve(CONTAINER_CAPACITY);
363    }
364}
365
366impl Recording {
367    /// Creates an empty recording.
368    pub fn new() -> Recording {
369        Recording::default()
370    }
371
372    /// Returns a sink that records a value into this recording.
373    ///
374    /// A previously recorded value is discarded.
375    pub fn recorder<'de>(&mut self, state: &mut State) -> SinkHandle<'_, 'de> {
376        self.0.events.clear();
377        self.0.is_map_key = false;
378        SinkHandle::arena(
379            Recorder {
380                target: self,
381                end: None,
382                start: 0,
383                is_root: true,
384            },
385            state,
386        )
387    }
388
389    /// Returns a sink that records a value and passes the recording to a
390    /// callback once the value is complete.
391    ///
392    /// This is useful for types which need to see the complete value before
393    /// they can deserialize it, like untagged enums which try to replay the
394    /// value into different types.
395    ///
396    /// ```
397    /// use deser::State;
398    /// use deser::de::{Deserialize, Recording, SinkHandle};
399    ///
400    /// /// Deserializes either as number or as string.
401    /// #[derive(Debug, PartialEq)]
402    /// enum NumberOrString {
403    ///     Number(u64),
404    ///     String(String),
405    /// }
406    ///
407    /// impl<'de> Deserialize<'de> for NumberOrString {
408    ///     fn deserialize_into<'out>(
409    ///         out: &'out mut Option<Self>,
410    ///         state: &mut State,
411    ///     ) -> SinkHandle<'out, 'de> {
412    ///         Recording::capture(move |recording, state| {
413    ///             let mut number = None;
414    ///             let sink = u64::deserialize_into(&mut number, state);
415    ///             if recording.replay(sink, state).is_ok() {
416    ///                 *out = number.map(NumberOrString::Number);
417    ///             } else {
418    ///                 let mut string = None;
419    ///                 let sink = String::deserialize_into(&mut string, state);
420    ///                 recording.replay(sink, state)?;
421    ///                 *out = string.map(NumberOrString::String);
422    ///             }
423    ///             Ok(())
424    ///         }, state)
425    ///     }
426    /// }
427    ///
428    /// let values: Vec<NumberOrString> = {
429    ///     let mut out = None;
430    ///     {
431    ///         let mut driver = deser::de::DeserializeDriver::new(&mut out);
432    ///         for event in [
433    ///             deser::Event::seq_start(),
434    ///             42u64.into(),
435    ///             "x".into(),
436    ///             deser::Event::SeqEnd,
437    ///         ] {
438    ///             driver.emit(event).unwrap();
439    ///         }
440    ///     }
441    ///     out.unwrap()
442    /// };
443    /// assert_eq!(
444    ///     values,
445    ///     [NumberOrString::Number(42), NumberOrString::String("x".into())]
446    /// );
447    /// ```
448    pub fn capture<'a, 'de, F>(then: F, state: &mut State) -> SinkHandle<'a, 'de>
449    where
450        F: FnOnce(Recording, &mut State) -> Result<(), Error> + Send + 'a,
451    {
452        SinkHandle::arena(
453            CaptureSink {
454                recording: Recording::new(),
455                end: None,
456                then: Some(FnCapture(Some(then))),
457            },
458            state,
459        )
460    }
461
462    /// Returns `true` if nothing was recorded.
463    pub fn is_empty(&self) -> bool {
464        self.0.is_empty()
465    }
466
467    /// Returns the recorded events.
468    pub fn events(&self) -> impl Iterator<Item = &Event<'static>> {
469        self.0.events.iter().map(|recorded| &recorded.event)
470    }
471
472    /// Returns the value if the recording is a single string.
473    ///
474    /// This is useful to look at recorded map keys.
475    pub fn as_str(&self) -> Option<&str> {
476        self.0.as_str()
477    }
478
479    /// Replays the recorded value into a sink.
480    ///
481    /// The state is the state of the ongoing deserialization.  The replayable
482    /// extensions in it are restored to their current values after replaying.
483    pub fn replay<'de>(&self, sink: SinkHandle<'_, 'de>, state: &mut State) -> Result<(), Error> {
484        self.0.replay(sink, state)
485    }
486}
487
488impl<'de> RecordBuf<'de> {
489    /// Creates an empty buffer.
490    pub fn new() -> RecordBuf<'de> {
491        RecordBuf::default()
492    }
493
494    /// Returns a sink that records a value into this buffer.
495    ///
496    /// A previously recorded value is discarded.
497    pub fn recorder(&mut self, state: &mut State) -> SinkHandle<'_, 'de> {
498        self.events.clear();
499        self.is_map_key = false;
500        SinkHandle::arena(
501            Recorder {
502                target: self,
503                end: None,
504                start: 0,
505                is_root: true,
506            },
507            state,
508        )
509    }
510
511    /// Returns a sink that records a value and passes the buffer to a
512    /// callback once the value is complete (see [`Recording::capture`]).
513    pub fn capture<'a, F>(then: F, state: &mut State) -> SinkHandle<'a, 'de>
514    where
515        F: FnOnce(RecordBuf<'de>, &mut State) -> Result<(), Error> + Send + 'a,
516        'de: 'a,
517    {
518        RecordBuf::capture_with(FnCapture(Some(then)), state)
519    }
520
521    /// Returns a sink that captures a value and passes it on.
522    ///
523    /// Unlike [`capture`](Self::capture) values which are a single atom are
524    /// passed on without recording them.
525    #[cfg_attr(not(feature = "derive"), allow(dead_code))]
526    pub(crate) fn capture_with<'a, C: Capture<'de, RecordBuf<'de>> + 'a>(
527        then: C,
528        state: &mut State,
529    ) -> SinkHandle<'a, 'de>
530    where
531        'de: 'a,
532    {
533        SinkHandle::arena(
534            CaptureSink {
535                recording: RecordBuf::new(),
536                end: None,
537                then: Some(then),
538            },
539            state,
540        )
541    }
542
543    /// Records a single atom, discarding a previously recorded value.
544    #[cfg_attr(not(feature = "derive"), allow(dead_code))]
545    pub(crate) fn set_atom(&mut self, atom: &Atom<'_>, state: &State) {
546        self.events.clear();
547        self.is_map_key = false;
548        record(self, true, Event::Atom(atom.to_static()), false, state);
549    }
550
551    /// Returns the start of the input range of the first event.
552    #[cfg_attr(not(feature = "derive"), allow(dead_code))]
553    pub(crate) fn offset(&self) -> Option<usize> {
554        self.events
555            .first()
556            .map(|x| x.input_range.0)
557            .filter(|&x| x != crate::state::NO_RANGE.0)
558    }
559
560    /// Attaches the context of the first event to an error.
561    ///
562    /// This is for errors about the recorded value that are not returned
563    /// while it's replayed.
564    #[cfg_attr(not(feature = "derive"), allow(dead_code))]
565    pub(crate) fn attach_context(&self, err: Error, state: &mut State) -> Error {
566        let Some(first) = self.events.first() else {
567            return state.attach_error_context(err);
568        };
569        let live = state.extensions().snapshot();
570        let live_range = state.input_range;
571        state.input_range = first.input_range;
572        first.restore(state);
573        let err = state.attach_error_context(err);
574        state.extensions_mut().restore(&live);
575        state.input_range = live_range;
576        err
577    }
578
579    /// Returns `true` if nothing was recorded.
580    pub fn is_empty(&self) -> bool {
581        self.events.is_empty()
582    }
583
584    /// Returns the atom if the buffer is a single atom.
585    #[cfg_attr(not(feature = "derive"), allow(dead_code))]
586    pub(crate) fn single_atom(&self) -> Option<&Atom<'de>> {
587        match self.events.as_slice() {
588            [
589                RecordedEvent {
590                    event: Event::Atom(atom),
591                    ..
592                },
593            ] => Some(atom),
594            _ => None,
595        }
596    }
597
598    /// Returns the value if the buffer is a single string.
599    pub fn as_str(&self) -> Option<&str> {
600        self.single_atom()?.as_str()
601    }
602
603    /// Replays the recorded value into a sink.
604    ///
605    /// Atoms that were delivered borrowed are replayed borrowed.
606    pub fn replay<'a>(&self, sink: SinkHandle<'_, 'a>, state: &mut State) -> Result<(), Error>
607    where
608        'de: 'a,
609    {
610        let live = state.extensions().snapshot_if_any();
611        let live_range = state.input_range;
612        let rv = self.replay_events(sink, state);
613        match live {
614            Some(live) => state.extensions_mut().restore(&live),
615            // restoring an empty snapshot only clears the event data
616            None => state.clear_event_data(),
617        }
618        state.input_range = live_range;
619        rv
620    }
621
622    fn replay_events<'a>(&self, sink: SinkHandle<'_, 'a>, state: &mut State) -> Result<(), Error>
623    where
624        'de: 'a,
625    {
626        DeserializeDriver::nested(state, sink, self.is_map_key, |driver| {
627            for recorded in self.events.iter() {
628                let state = driver.state_mut();
629                state.input_range = recorded.input_range;
630                recorded.restore(state);
631                match recorded.event {
632                    Event::Atom(ref atom) if recorded.borrowed => {
633                        driver.emit_borrowed(Event::Atom(atom.clone()))?
634                    }
635                    ref event => driver.emit(event.as_borrowed())?,
636                }
637            }
638            Ok(())
639        })
640    }
641}
642
643fn record<'de>(
644    buf: &mut RecordBuf<'de>,
645    is_root: bool,
646    event: Event<'de>,
647    borrowed: bool,
648    state: &State,
649) {
650    if is_root && buf.events.is_empty() {
651        buf.is_map_key = state.is_map_key();
652    }
653    let recorded = RecordedEvent {
654        span: match event {
655            Event::Atom(_) => 1,
656            _ => 0,
657        },
658        event,
659        borrowed,
660        input_range: state.input_range,
661        snapshot: state.extensions().snapshot_if_any().map(Box::new),
662    };
663    // the events of containers go to the vector directly
664    match buf.events {
665        Events::Heap(ref mut events) => events.push(recorded),
666        ref mut events => events.push(recorded),
667    }
668}
669
670/// Receives a value that was captured (see [`RecordBuf::capture_with`]).
671pub(crate) trait Capture<'de, T>: Send {
672    /// Receives a value that is a single atom.
673    ///
674    /// The atom is passed on as it is, without recording it.
675    fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error>;
676
677    /// Receives a value that is a single atom which borrows from the data.
678    fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
679        self.atom(atom, state)
680    }
681
682    /// Receives the recording of any other value.
683    fn recorded(&mut self, recording: T, state: &mut State) -> Result<(), Error>;
684}
685
686/// Passes every captured value to a callback as recording.
687struct FnCapture<F>(Option<F>);
688
689impl<'de, T, F> Capture<'de, T> for FnCapture<F>
690where
691    T: Target<'de> + Default,
692    F: FnOnce(T, &mut State) -> Result<(), Error> + Send,
693{
694    fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
695        let mut recording = T::default();
696        recording.push(true, Event::Atom(atom.to_static()), state);
697        self.recorded(recording, state)
698    }
699
700    fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
701        let mut recording = T::default();
702        recording.push_borrowed(true, atom, state);
703        self.recorded(recording, state)
704    }
705
706    fn recorded(&mut self, recording: T, state: &mut State) -> Result<(), Error> {
707        match self.0.take() {
708            Some(then) => then(recording, state),
709            None => Ok(()),
710        }
711    }
712}
713
714/// Records a value and passes it on.
715struct CaptureSink<T, C> {
716    recording: T,
717    end: Option<Event<'static>>,
718    // `None` once the value was passed on
719    then: Option<C>,
720}
721
722impl<'de, T, C> CaptureSink<T, C> {
723    fn child(&mut self, state: &mut State) -> SinkHandle<'_, 'de>
724    where
725        T: Target<'de>,
726    {
727        SinkHandle::arena(
728            Recorder {
729                target: &mut self.recording,
730                end: None,
731                start: 0,
732                is_root: false,
733            },
734            state,
735        )
736    }
737}
738
739impl<'de, T: Target<'de> + Default, C: Capture<'de, T>> Sink<'de> for CaptureSink<T, C> {
740    fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
741        match self.then.take() {
742            Some(mut then) => then.atom(atom, state),
743            None => Ok(()),
744        }
745    }
746
747    fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
748        match self.then.take() {
749            Some(mut then) => then.borrowed_atom(atom, state),
750            None => Ok(()),
751        }
752    }
753
754    fn map(&mut self, state: &mut State) -> Result<(), Error> {
755        let shape = state.container_shape();
756        // containers have a few events at least, skip the smallest sizes
757        self.recording.reserve();
758        self.recording.push(true, Event::MapStart(shape), state);
759        self.end = Some(Event::MapEnd);
760        Ok(())
761    }
762
763    fn seq(&mut self, state: &mut State) -> Result<(), Error> {
764        let shape = state.container_shape();
765        self.recording.reserve();
766        self.recording.push(true, Event::SeqStart(shape), state);
767        self.end = Some(Event::SeqEnd);
768        Ok(())
769    }
770
771    fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
772        Ok(self.child(state))
773    }
774
775    fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
776        Ok(self.child(state))
777    }
778
779    // atoms in the container are recorded without creating a sink for them
780
781    fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
782        self.recording
783            .push(false, Event::Atom(atom.to_static()), state);
784        Ok(())
785    }
786
787    fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
788        self.recording
789            .push(false, Event::Atom(atom.to_static()), state);
790        Ok(())
791    }
792
793    fn __private_borrowed_key_atom(
794        &mut self,
795        atom: Atom<'de>,
796        state: &mut State,
797    ) -> Result<(), Error> {
798        self.recording.push_borrowed(false, atom, state);
799        Ok(())
800    }
801
802    fn __private_borrowed_value_atom(
803        &mut self,
804        atom: Atom<'de>,
805        state: &mut State,
806    ) -> Result<(), Error> {
807        self.recording.push_borrowed(false, atom, state);
808        Ok(())
809    }
810
811    /// Takes all keys if the recording is flattened into a struct.
812    ///
813    /// The keys are recorded as a map.
814    fn value_for_key(
815        &mut self,
816        key: &str,
817        state: &mut State,
818    ) -> Result<Option<SinkHandle<'_, 'de>>, Error> {
819        match self.end {
820            Some(Event::MapEnd) => {}
821            None if self.recording.is_empty() => {
822                self.recording
823                    .push(true, Event::MapStart(ContainerShape::new()), state);
824                self.end = Some(Event::MapEnd);
825            }
826            _ => return Ok(None),
827        }
828        self.recording
829            .push(false, Event::Atom(Atom::Str(key.to_owned().into())), state);
830        Ok(Some(self.child(state)))
831    }
832
833    fn finish(&mut self, state: &mut State) -> Result<(), Error> {
834        // an atom was already passed on
835        let Some(mut then) = self.then.take() else {
836            return Ok(());
837        };
838        if self.recording.is_empty() && self.end.is_none() {
839            // flattened into a struct but no key was given
840            self.recording
841                .push(true, Event::MapStart(ContainerShape::new()), state);
842            self.end = Some(Event::MapEnd);
843        }
844        if let Some(end) = self.end.take() {
845            self.recording.push(true, end, state);
846            // the container is the first event of the recording
847            self.recording.close(0);
848        }
849        then.recorded(core::mem::take(&mut self.recording), state)
850    }
851}
852
853/// Records a single value into a recording.
854struct Recorder<'a, T> {
855    target: &'a mut T,
856    end: Option<Event<'static>>,
857    // the index of the start event if the value is a container
858    start: usize,
859    is_root: bool,
860}
861
862impl<'a, T> Recorder<'a, T> {
863    fn child<'de>(&mut self, state: &mut State) -> SinkHandle<'_, 'de>
864    where
865        T: Target<'de>,
866    {
867        SinkHandle::arena(
868            Recorder {
869                target: &mut *self.target,
870                end: None,
871                start: 0,
872                is_root: false,
873            },
874            state,
875        )
876    }
877}
878
879impl<'a, 'de, T: Target<'de>> Sink<'de> for Recorder<'a, T> {
880    fn atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
881        self.target
882            .push(self.is_root, Event::Atom(atom.to_static()), state);
883        Ok(())
884    }
885
886    fn borrowed_atom(&mut self, atom: Atom<'de>, state: &mut State) -> Result<(), Error> {
887        self.target.push_borrowed(self.is_root, atom, state);
888        Ok(())
889    }
890
891    fn map(&mut self, state: &mut State) -> Result<(), Error> {
892        self.start = self.target.len();
893        self.target.push(
894            self.is_root,
895            Event::MapStart(state.container_shape()),
896            state,
897        );
898        self.end = Some(Event::MapEnd);
899        Ok(())
900    }
901
902    fn seq(&mut self, state: &mut State) -> Result<(), Error> {
903        self.start = self.target.len();
904        self.target.push(
905            self.is_root,
906            Event::SeqStart(state.container_shape()),
907            state,
908        );
909        self.end = Some(Event::SeqEnd);
910        Ok(())
911    }
912
913    fn next_key(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
914        Ok(self.child(state))
915    }
916
917    fn next_value(&mut self, state: &mut State) -> Result<SinkHandle<'_, 'de>, Error> {
918        Ok(self.child(state))
919    }
920
921    // atoms in the container are recorded without creating a sink for them
922
923    fn __private_key_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
924        self.target
925            .push(false, Event::Atom(atom.to_static()), state);
926        Ok(())
927    }
928
929    fn __private_value_atom(&mut self, atom: Atom, state: &mut State) -> Result<(), Error> {
930        self.target
931            .push(false, Event::Atom(atom.to_static()), state);
932        Ok(())
933    }
934
935    fn __private_borrowed_key_atom(
936        &mut self,
937        atom: Atom<'de>,
938        state: &mut State,
939    ) -> Result<(), Error> {
940        self.target.push_borrowed(false, atom, state);
941        Ok(())
942    }
943
944    fn __private_borrowed_value_atom(
945        &mut self,
946        atom: Atom<'de>,
947        state: &mut State,
948    ) -> Result<(), Error> {
949        self.target.push_borrowed(false, atom, state);
950        Ok(())
951    }
952    fn finish(&mut self, state: &mut State) -> Result<(), Error> {
953        if let Some(end) = self.end.take() {
954            self.target.push(self.is_root, end, state);
955            self.target.close(self.start);
956        }
957        Ok(())
958    }
959}
960
961/// Recordings are compared by their events.
962///
963/// The event data and the replayable extensions captured with the events
964/// are not compared.
965impl PartialEq for Recording {
966    fn eq(&self, other: &Self) -> bool {
967        self.0.events.len() == other.0.events.len()
968            && self
969                .0
970                .events
971                .iter()
972                .zip(other.0.events.iter())
973                .all(|(a, b)| a.event == b.event)
974    }
975}
976
977impl<'de> Deserialize<'de> for Recording {
978    fn deserialize_into<'out>(
979        out: &'out mut Option<Self>,
980        state: &mut State,
981    ) -> SinkHandle<'out, 'de> {
982        Recording::capture(
983            move |recording, _state| {
984                *out = Some(recording);
985                Ok(())
986            },
987            state,
988        )
989    }
990}
991
992/// Returns the number of events of the value the events start with.
993///
994/// Atoms and closed containers know their number of events, other values
995/// are scanned.
996#[inline]
997fn value_len(events: &[RecordedEvent<'_>]) -> usize {
998    match events.first() {
999        Some(first) if first.span != 0 => first.span as usize,
1000        _ => scan_value_len(events),
1001    }
1002}
1003
1004/// Returns the number of events of a value by looking for its end.
1005#[cold]
1006fn scan_value_len(events: &[RecordedEvent<'_>]) -> usize {
1007    let mut depth = 0usize;
1008    for (index, recorded) in events.iter().enumerate() {
1009        match recorded.event {
1010            Event::MapStart(_) | Event::SeqStart(_) => depth += 1,
1011            Event::MapEnd | Event::SeqEnd => depth = depth.saturating_sub(1),
1012            Event::Atom(_) => {}
1013        }
1014        if depth == 0 {
1015            return index + 1;
1016        }
1017    }
1018    events.len()
1019}
1020
1021/// Closes the container starting at `start` after its end was recorded.
1022///
1023/// The number of events of the container is stored in its start event,
1024/// which makes skipping over it cheap when the recording is serialized.
1025/// The containers in it were closed before, so this only walks over its
1026/// elements.  If the format did not know the length of the container, the
1027/// number of elements is stored in its shape: it's known now, and
1028/// serializers can use it (for instance to write the header of the
1029/// container right away in binary formats) as can sinks that preallocate.
1030fn close(events: &mut [RecordedEvent<'_>], start: usize) {
1031    let Some((head, rest)) = events.get_mut(start..).and_then(|x| x.split_first_mut()) else {
1032        return;
1033    };
1034    // values of more than `u32::MAX` events are scanned
1035    head.span = u32::try_from(rest.len() + 1).unwrap_or(0);
1036    let is_map = match head.event {
1037        Event::MapStart(shape) if shape.len().is_none() => true,
1038        Event::SeqStart(shape) if shape.len().is_none() => false,
1039        _ => return,
1040    };
1041    let inner = &rest[..rest.len().saturating_sub(1)];
1042    let mut count = 0;
1043    let mut index = 0;
1044    while index < inner.len() {
1045        index += value_len(&inner[index..]);
1046        count += 1;
1047    }
1048    if let Event::MapStart(ref mut shape) | Event::SeqStart(ref mut shape) = head.event {
1049        *shape = shape.with_len(if is_map { count / 2 } else { count });
1050    }
1051}
1052
1053/// A recorded value that is serialized.
1054struct RecordedValue<'a, 'de>(&'a [RecordedEvent<'de>]);
1055
1056impl<'a, 'de> RecordedValue<'a, 'de> {
1057    fn chunk(&self, state: &mut State) -> Result<Chunk<'a>, Error> {
1058        let events = self.0;
1059        let (first, snapshot) = match events.first() {
1060            Some(first) => (&first.event, &first.snapshot),
1061            None => {
1062                return Err(Error::new(
1063                    ErrorKind::Unexpected,
1064                    "cannot serialize an empty recording",
1065                ));
1066            }
1067        };
1068        // the recorded data is added to the data that a wrapper of the
1069        // recording (like one that adds a tag) attached
1070        if let Some(snapshot) = snapshot {
1071            state.attach_event_data(snapshot.event_data());
1072        }
1073        let inner = events.get(1..events.len().saturating_sub(1)).unwrap_or(&[]);
1074        Ok(match first {
1075            Event::Atom(atom) => Chunk::Atom(atom.as_borrowed()),
1076            Event::MapStart(_) => Chunk::map(
1077                RecordedEmitter {
1078                    rest: inner,
1079                    current: RecordedValue(&[]),
1080                },
1081                state,
1082            ),
1083            Event::SeqStart(_) => Chunk::seq(
1084                RecordedEmitter {
1085                    rest: inner,
1086                    current: RecordedValue(&[]),
1087                },
1088                state,
1089            ),
1090            Event::MapEnd | Event::SeqEnd => {
1091                return Err(Error::new(ErrorKind::Unexpected, "malformed recording"));
1092            }
1093        })
1094    }
1095
1096    fn container_shape(&self) -> ContainerShape {
1097        match self.0.first().map(|x| &x.event) {
1098            Some(Event::MapStart(shape) | Event::SeqStart(shape)) => *shape,
1099            _ => ContainerShape::new(),
1100        }
1101    }
1102
1103    fn is_optional(&self) -> bool {
1104        matches!(
1105            self.0,
1106            [RecordedEvent {
1107                event: Event::Atom(Atom::Null),
1108                ..
1109            }]
1110        )
1111    }
1112}
1113
1114impl Serialize for RecordedValue<'_, '_> {
1115    fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
1116        self.chunk(state)
1117    }
1118
1119    fn container_shape(&self) -> ContainerShape {
1120        RecordedValue::container_shape(self)
1121    }
1122}
1123
1124/// Emits the values of a recorded map or sequence.
1125struct RecordedEmitter<'a, 'de> {
1126    rest: &'a [RecordedEvent<'de>],
1127    current: RecordedValue<'a, 'de>,
1128}
1129
1130impl RecordedEmitter<'_, '_> {
1131    fn next_value(&mut self) -> Option<SerializeHandle<'_>> {
1132        if self.rest.is_empty() {
1133            return None;
1134        }
1135        let len = value_len(self.rest);
1136        let (value, rest) = self.rest.split_at(len);
1137        self.current = RecordedValue(value);
1138        self.rest = rest;
1139        Some(SerializeHandle::to(&self.current))
1140    }
1141}
1142
1143impl SeqEmitter for RecordedEmitter<'_, '_> {
1144    fn next(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
1145        Ok(self.next_value())
1146    }
1147}
1148
1149impl MapEmitter for RecordedEmitter<'_, '_> {
1150    fn next_key(&mut self, _state: &mut State) -> Result<Option<SerializeHandle<'_>>, Error> {
1151        Ok(self.next_value())
1152    }
1153
1154    fn next_value(&mut self, _state: &mut State) -> Result<SerializeHandle<'_>, Error> {
1155        RecordedEmitter::next_value(self)
1156            .ok_or_else(|| Error::new(ErrorKind::Unexpected, "malformed recording"))
1157    }
1158}
1159
1160impl Serialize for Recording {
1161    fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
1162        RecordedValue(self.0.events.as_slice()).chunk(state)
1163    }
1164
1165    fn container_shape(&self) -> ContainerShape {
1166        RecordedValue(self.0.events.as_slice()).container_shape()
1167    }
1168
1169    fn is_optional(&self) -> bool {
1170        RecordedValue(self.0.events.as_slice()).is_optional()
1171    }
1172}
1173
1174/// Record buffers serialize like [`Recording`]s, borrowed atoms are
1175/// serialized without copying them.
1176impl Serialize for RecordBuf<'_> {
1177    fn serialize(&self, state: &mut State) -> Result<Chunk<'_>, Error> {
1178        RecordedValue(self.events.as_slice()).chunk(state)
1179    }
1180
1181    fn container_shape(&self) -> ContainerShape {
1182        RecordedValue(self.events.as_slice()).container_shape()
1183    }
1184
1185    fn is_optional(&self) -> bool {
1186        RecordedValue(self.events.as_slice()).is_optional()
1187    }
1188}
1189
1190/// Record buffers deserialize like [`Recording`]s but keep borrowed atoms
1191/// borrowed.
1192impl<'de> Deserialize<'de> for RecordBuf<'de> {
1193    fn deserialize_into<'out>(
1194        out: &'out mut Option<Self>,
1195        state: &mut State,
1196    ) -> SinkHandle<'out, 'de> {
1197        RecordBuf::capture(
1198            move |buf, _state| {
1199                *out = Some(buf);
1200                Ok(())
1201            },
1202            state,
1203        )
1204    }
1205}