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