sbor/traversal/untyped/
traverser.rs

1use super::*;
2use crate::decoder::BorrowingDecoder;
3use crate::rust::prelude::*;
4use crate::rust::str;
5use crate::value_kind::*;
6use crate::*;
7
8/// Returns the length of the value at the start of the partial payload.
9pub fn calculate_value_tree_body_byte_length<'de, 's, E: CustomExtension>(
10    partial_payload: &'de [u8],
11    value_kind: ValueKind<E::CustomValueKind>,
12    current_depth: usize,
13    depth_limit: usize,
14) -> Result<usize, DecodeError> {
15    let mut traverser = VecTraverser::<E::CustomTraversal>::new(
16        partial_payload,
17        ExpectedStart::ValueBody(value_kind),
18        VecTraverserConfig {
19            max_depth: depth_limit - current_depth,
20            check_exact_end: false,
21        },
22    );
23    loop {
24        let next_event = traverser.next_event();
25        match next_event.event {
26            TraversalEvent::End => return Ok(next_event.location.end_offset),
27            TraversalEvent::DecodeError(decode_error) => return Err(decode_error),
28            _ => {}
29        }
30    }
31}
32
33pub trait CustomTraversal: Copy + Debug + Clone + PartialEq + Eq {
34    type CustomValueKind: CustomValueKind;
35    type CustomTerminalValueRef<'de>: CustomTerminalValueRef<
36        CustomValueKind = Self::CustomValueKind,
37    >;
38
39    fn read_custom_value_body<'de, R>(
40        custom_value_kind: Self::CustomValueKind,
41        reader: &mut R,
42    ) -> Result<Self::CustomTerminalValueRef<'de>, DecodeError>
43    where
44        R: BorrowingDecoder<'de, Self::CustomValueKind>;
45}
46
47pub trait CustomTerminalValueRef: Debug + Clone + PartialEq + Eq {
48    type CustomValueKind: CustomValueKind;
49
50    fn custom_value_kind(&self) -> Self::CustomValueKind;
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub struct AncestorState<T: CustomTraversal> {
55    pub container_header: ContainerHeader<T>,
56    /// The byte offset of the start of the container in the input buffer
57    pub container_start_offset: usize,
58    /// Goes from 0,... container_header.child_count() - 1 as children in the container are considered.
59    /// NOTE: For maps, container_header.child_count() = 2 * Map length
60    ///
61    /// The `current_child_index` does NOT necessarily point at a valid value which can be decoded,
62    /// - the index is updated before the child is read, to record errors against it.
63    pub current_child_index: usize,
64}
65
66impl<T: CustomTraversal> AncestorState<T> {
67    #[inline]
68    fn get_implicit_value_kind_of_current_child(&self) -> Option<ValueKind<T::CustomValueKind>> {
69        self.container_header
70            .get_implicit_child_value_kind(self.current_child_index)
71    }
72}
73
74/// The `VecTraverser` is for streamed decoding of a payload or single encoded value (tree).
75/// It turns payload decoding into a pull-based event stream.
76///
77/// The caller is responsible for stopping calling `next_event` after an Error or End event.
78pub struct VecTraverser<'de, T: CustomTraversal> {
79    decoder: VecDecoder<'de, T::CustomValueKind>,
80    ancestor_path: Vec<AncestorState<T>>,
81    next_action: NextAction<T>,
82    config: VecTraverserConfig,
83}
84
85pub struct VecTraverserConfig {
86    pub max_depth: usize,
87    pub check_exact_end: bool,
88}
89
90#[derive(Debug, Clone, Copy)]
91pub enum NextAction<T: CustomTraversal> {
92    ReadPrefix {
93        expected_prefix: u8,
94    },
95    ReadRootValue,
96    ReadRootValueBody {
97        implicit_value_kind: ValueKind<T::CustomValueKind>,
98    },
99    ReadContainerContentStart {
100        container_header: ContainerHeader<T>,
101        container_start_offset: usize,
102    },
103    /// The state which is put into after entering parent, and
104    /// the default state to return to from below
105    ReadNextChildOrExitContainer,
106    Errored,
107    Ended,
108    /// Impossible to observe this value
109    InProgressPlaceholder,
110}
111
112#[derive(Debug, Clone, Copy)]
113pub enum ExpectedStart<X: CustomValueKind> {
114    PayloadPrefix(u8),
115    Value,
116    ValueBody(ValueKind<X>),
117}
118
119impl<'de, T: CustomTraversal> VecTraverser<'de, T> {
120    pub fn new(
121        input: &'de [u8],
122        expected_start: ExpectedStart<T::CustomValueKind>,
123        config: VecTraverserConfig,
124    ) -> Self {
125        Self {
126            // Note that the VecTraverser needs to be very low level for performance,
127            // so purposefully doesn't use the depth tracking in the decoder itself.
128            // But we set a max depth anyway, for safety.
129            decoder: VecDecoder::new(input, config.max_depth),
130            ancestor_path: Vec::with_capacity(config.max_depth),
131            next_action: match expected_start {
132                ExpectedStart::PayloadPrefix(prefix) => NextAction::ReadPrefix {
133                    expected_prefix: prefix,
134                },
135                ExpectedStart::Value => NextAction::ReadRootValue,
136                ExpectedStart::ValueBody(value_kind) => NextAction::ReadRootValueBody {
137                    implicit_value_kind: value_kind,
138                },
139            },
140            config,
141        }
142    }
143
144    pub fn next_event<'t>(&'t mut self) -> LocatedTraversalEvent<'t, 'de, T> {
145        let (event, next_action) = Self::step(
146            core::mem::replace(&mut self.next_action, NextAction::InProgressPlaceholder),
147            &self.config,
148            &mut self.decoder,
149            &mut self.ancestor_path,
150        );
151        self.next_action = next_action;
152        event
153    }
154
155    #[inline]
156    fn step<'t, 'd>(
157        action: NextAction<T>,
158        config: &VecTraverserConfig,
159        decoder: &'d mut VecDecoder<'de, T::CustomValueKind>,
160        ancestor_path: &'t mut Vec<AncestorState<T>>,
161    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
162        match action {
163            NextAction::ReadPrefix { expected_prefix } => {
164                // The reading of the prefix has no associated event, so we perform the prefix check first,
165                // and then proceed to read the root value if it succeeds.
166                let start_offset = decoder.get_offset();
167                match decoder.read_and_check_payload_prefix(expected_prefix) {
168                    Ok(()) => {
169                        // Prefix read successfully. Now read root value.
170                        ActionHandler::new_from_current_offset(ancestor_path, decoder)
171                            .read_value(None)
172                    }
173                    Err(error) => {
174                        ActionHandler::new_with_fixed_offset(ancestor_path, decoder, start_offset)
175                            .complete_with_error(error)
176                    }
177                }
178            }
179            NextAction::ReadRootValue => {
180                ActionHandler::new_from_current_offset(ancestor_path, decoder).read_value(None)
181            }
182            NextAction::ReadRootValueBody {
183                implicit_value_kind,
184            } => ActionHandler::new_from_current_offset(ancestor_path, decoder)
185                .read_value(Some(implicit_value_kind)),
186            NextAction::ReadContainerContentStart {
187                container_header,
188                container_start_offset,
189            } => {
190                let container_child_size = container_header.get_child_count();
191                if container_child_size == 0 {
192                    // If the container has no children, we immediately container end without ever bothering
193                    // adding it as an ancestor.
194                    return ActionHandler::new_with_fixed_offset(
195                        ancestor_path,
196                        decoder,
197                        container_start_offset,
198                    )
199                    .complete_container_end(container_header);
200                }
201
202                // Add ancestor before checking for max depth so that the ancestor stack is
203                // correct if the depth check returns an error
204                ancestor_path.push(AncestorState {
205                    container_header,
206                    container_start_offset,
207                    current_child_index: 0,
208                });
209                // We know we're about to read a child at depth ancestor_path.len() + 1 - so
210                // it's an error if ancestor_path.len() >= config.max_depth.
211                // (We avoid the +1 so that we don't need to worry about overflow).
212                if ancestor_path.len() >= config.max_depth {
213                    return ActionHandler::new_from_current_offset(ancestor_path, decoder)
214                        .complete_with_error(DecodeError::MaxDepthExceeded(config.max_depth));
215                }
216
217                let parent = ancestor_path.last_mut().unwrap();
218                let parent_container = &parent.container_header;
219                let is_byte_array = matches!(
220                    parent_container,
221                    ContainerHeader::Array(ArrayHeader {
222                        element_value_kind: ValueKind::U8,
223                        ..
224                    })
225                );
226                // If it's a byte array, we do a batch-read optimisation
227                if is_byte_array {
228                    // We know this is >= 1 from the above check
229                    let array_length = container_child_size;
230                    let max_index_which_would_be_read = array_length - 1;
231                    // Set current child index before we read so that if we get an error on read
232                    // then it comes through at the max child index we attempted to read.
233                    parent.current_child_index = max_index_which_would_be_read;
234                    ActionHandler::new_from_current_offset(ancestor_path, decoder)
235                        .read_byte_array(array_length)
236                } else {
237                    // NOTE: parent.current_child_index is already 0, so no need to change it
238                    let implicit_value_kind = parent.get_implicit_value_kind_of_current_child();
239                    ActionHandler::new_from_current_offset(ancestor_path, decoder)
240                        .read_value(implicit_value_kind)
241                }
242            }
243            NextAction::ReadNextChildOrExitContainer => {
244                let parent = ancestor_path.last_mut();
245                match parent {
246                    Some(parent) => {
247                        let next_child_index = parent.current_child_index + 1;
248                        let is_complete =
249                            next_child_index >= parent.container_header.get_child_count();
250                        if is_complete {
251                            // We pop the completed parent from the ancestor list
252                            let AncestorState {
253                                container_header,
254                                container_start_offset,
255                                ..
256                            } = ancestor_path.pop().expect("Parent has just been read");
257
258                            ActionHandler::new_with_fixed_offset(
259                                ancestor_path,
260                                decoder,
261                                container_start_offset,
262                            )
263                            .complete_container_end(container_header)
264                        } else {
265                            parent.current_child_index = next_child_index;
266                            let implicit_value_kind =
267                                parent.get_implicit_value_kind_of_current_child();
268                            ActionHandler::new_from_current_offset(ancestor_path, decoder)
269                                .read_value(implicit_value_kind)
270                        }
271                    }
272                    None => {
273                        // We are due to read another element and exit but have no parent
274                        // This is because we have finished reading the `root` value.
275                        // Therefore we call `end`.
276                        ActionHandler::new_from_current_offset(ancestor_path, decoder).end(config)
277                    }
278                }
279            }
280            NextAction::Errored => {
281                panic!("It is unsupported to call `next_event` on a traverser which has returned an error.")
282            }
283            NextAction::Ended => {
284                panic!("It is unsupported to call `next_event` on a traverser which has already emitted an end event.")
285            }
286            NextAction::InProgressPlaceholder => {
287                unreachable!("It is not possible to observe this value - it is a placeholder for rust memory safety.")
288            }
289        }
290    }
291}
292
293macro_rules! handle_error {
294    ($action_handler: expr, $result: expr$(,)?) => {{
295        match $result {
296            Ok(value) => value,
297            Err(error) => {
298                return $action_handler.complete_with_error(error);
299            }
300        }
301    }};
302}
303
304/// This is just an encapsulation to improve code quality by:
305/// * Removing code duplication by capturing the ancestor_path/decoder/start_offset in one place
306/// * Ensuring code correctness by fixing the ancestor path
307struct ActionHandler<'t, 'd, 'de, T: CustomTraversal> {
308    ancestor_path: &'t [AncestorState<T>],
309    decoder: &'d mut VecDecoder<'de, T::CustomValueKind>,
310    start_offset: usize,
311}
312
313impl<'t, 'd, 'de, T: CustomTraversal> ActionHandler<'t, 'd, 'de, T> {
314    #[inline]
315    fn new_from_current_offset(
316        ancestor_path: &'t [AncestorState<T>],
317        decoder: &'d mut VecDecoder<'de, T::CustomValueKind>,
318    ) -> Self {
319        let start_offset = decoder.get_offset();
320        Self {
321            ancestor_path,
322            decoder,
323            start_offset,
324        }
325    }
326
327    #[inline]
328    fn new_with_fixed_offset(
329        ancestor_path: &'t [AncestorState<T>],
330        decoder: &'d mut VecDecoder<'de, T::CustomValueKind>,
331        start_offset: usize,
332    ) -> Self {
333        Self {
334            ancestor_path,
335            decoder,
336            start_offset,
337        }
338    }
339
340    #[inline]
341    fn read_value(
342        self,
343        implicit_value_kind: Option<ValueKind<T::CustomValueKind>>,
344    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
345        let value_kind = match implicit_value_kind {
346            Some(value_kind) => value_kind,
347            None => handle_error!(self, self.decoder.read_value_kind()),
348        };
349        self.read_value_body(value_kind)
350    }
351
352    #[inline]
353    fn read_byte_array(
354        self,
355        array_length: usize,
356    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
357        let bytes = handle_error!(self, self.decoder.read_slice_from_payload(array_length));
358        self.complete(
359            TraversalEvent::TerminalValueBatch(TerminalValueBatchRef::U8(bytes)),
360            // This is the correct action to ensure we exit the container on the next step
361            NextAction::ReadNextChildOrExitContainer,
362        )
363    }
364
365    #[inline]
366    fn end(
367        self,
368        config: &VecTraverserConfig,
369    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
370        if config.check_exact_end {
371            handle_error!(self, self.decoder.check_end());
372        }
373        self.complete(TraversalEvent::End, NextAction::Ended)
374    }
375
376    #[inline]
377    fn read_value_body(
378        self,
379        value_kind: ValueKind<T::CustomValueKind>,
380    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
381        match value_kind {
382            ValueKind::Bool => self.read_terminal_value(value_kind, TerminalValueRef::Bool),
383            ValueKind::I8 => self.read_terminal_value(value_kind, TerminalValueRef::I8),
384            ValueKind::I16 => self.read_terminal_value(value_kind, TerminalValueRef::I16),
385            ValueKind::I32 => self.read_terminal_value(value_kind, TerminalValueRef::I32),
386            ValueKind::I64 => self.read_terminal_value(value_kind, TerminalValueRef::I64),
387            ValueKind::I128 => self.read_terminal_value(value_kind, TerminalValueRef::I128),
388            ValueKind::U8 => self.read_terminal_value(value_kind, TerminalValueRef::U8),
389            ValueKind::U16 => self.read_terminal_value(value_kind, TerminalValueRef::U16),
390            ValueKind::U32 => self.read_terminal_value(value_kind, TerminalValueRef::U32),
391            ValueKind::U64 => self.read_terminal_value(value_kind, TerminalValueRef::U64),
392            ValueKind::U128 => self.read_terminal_value(value_kind, TerminalValueRef::U128),
393            ValueKind::String => {
394                let length = handle_error!(self, self.decoder.read_size());
395                let bytes = handle_error!(self, self.decoder.read_slice_from_payload(length));
396                let string_body = handle_error!(
397                    self,
398                    str::from_utf8(bytes).map_err(|_| DecodeError::InvalidUtf8)
399                );
400                self.complete(
401                    TraversalEvent::TerminalValue(TerminalValueRef::String(string_body)),
402                    NextAction::ReadNextChildOrExitContainer,
403                )
404            }
405            ValueKind::Array => {
406                let element_value_kind = handle_error!(self, self.decoder.read_value_kind());
407                let length = handle_error!(self, self.decoder.read_size());
408                self.complete_container_start(ContainerHeader::Array(ArrayHeader {
409                    element_value_kind,
410                    length,
411                }))
412            }
413            ValueKind::Map => {
414                let key_value_kind = handle_error!(self, self.decoder.read_value_kind());
415                let value_value_kind = handle_error!(self, self.decoder.read_value_kind());
416                let length = handle_error!(self, self.decoder.read_size());
417                self.complete_container_start(ContainerHeader::Map(MapHeader {
418                    key_value_kind,
419                    value_value_kind,
420                    length,
421                }))
422            }
423            ValueKind::Enum => {
424                let variant = handle_error!(self, self.decoder.read_byte());
425                let length = handle_error!(self, self.decoder.read_size());
426                self.complete_container_start(ContainerHeader::EnumVariant(EnumVariantHeader {
427                    variant,
428                    length,
429                }))
430            }
431            ValueKind::Tuple => {
432                let length = handle_error!(self, self.decoder.read_size());
433                self.complete_container_start(ContainerHeader::Tuple(TupleHeader { length }))
434            }
435            ValueKind::Custom(custom_value_kind) => {
436                let custom_value_ref = handle_error!(
437                    self,
438                    T::read_custom_value_body(custom_value_kind, self.decoder)
439                );
440                self.complete(
441                    TraversalEvent::TerminalValue(TerminalValueRef::Custom(custom_value_ref)),
442                    NextAction::ReadNextChildOrExitContainer,
443                )
444            }
445        }
446    }
447
448    #[inline]
449    fn read_terminal_value<V: Decode<T::CustomValueKind, VecDecoder<'de, T::CustomValueKind>>>(
450        self,
451        value_kind: ValueKind<T::CustomValueKind>,
452        value_ref_constructor: impl Fn(V) -> TerminalValueRef<'de, T>,
453    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
454        match V::decode_body_with_value_kind(self.decoder, value_kind) {
455            Ok(value) => self.complete(
456                TraversalEvent::TerminalValue(value_ref_constructor(value)),
457                NextAction::ReadNextChildOrExitContainer,
458            ),
459            Err(error) => self.complete_with_error(error),
460        }
461    }
462
463    #[inline]
464    fn complete_container_start(
465        self,
466        container_header: ContainerHeader<T>,
467    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
468        let next_action = NextAction::ReadContainerContentStart {
469            container_header: container_header.clone(),
470            container_start_offset: self.start_offset,
471        };
472        self.complete(
473            TraversalEvent::ContainerStart(container_header),
474            next_action,
475        )
476    }
477
478    #[inline]
479    fn complete_container_end(
480        self,
481        container_header: ContainerHeader<T>,
482    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
483        self.complete(
484            TraversalEvent::ContainerEnd(container_header),
485            // Continue interating the parent
486            NextAction::ReadNextChildOrExitContainer,
487        )
488    }
489
490    #[inline]
491    fn complete_with_error(
492        self,
493        error: DecodeError,
494    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
495        self.complete(TraversalEvent::DecodeError(error), NextAction::Errored)
496    }
497
498    #[inline]
499    fn complete(
500        self,
501        traversal_event: TraversalEvent<'de, T>,
502        next_action: NextAction<T>,
503    ) -> (LocatedTraversalEvent<'t, 'de, T>, NextAction<T>) {
504        let located_event = LocatedTraversalEvent {
505            event: traversal_event,
506            location: Location {
507                start_offset: self.start_offset,
508                end_offset: self.decoder.get_offset(),
509                ancestor_path: self.ancestor_path,
510            },
511        };
512        (located_event, next_action)
513    }
514}
515
516#[cfg(test)]
517mod tests {
518    use crate::rust::prelude::*;
519
520    use super::*;
521
522    #[derive(Categorize, Encode)]
523    #[allow(dead_code)]
524    struct TestStruct {
525        x: u32,
526    }
527
528    #[derive(Categorize, Encode)]
529    #[allow(dead_code)]
530    enum TestEnum {
531        A { x: u32 },
532        B(u32),
533        C,
534    }
535
536    #[test]
537    pub fn test_calculate_value_tree_body_byte_array() {
538        let payload = basic_encode(&BasicValue::Array {
539            element_value_kind: BasicValueKind::Array,
540            elements: vec![BasicValue::Array {
541                element_value_kind: BasicValueKind::U8,
542                elements: vec![BasicValue::U8 { value: 44 }, BasicValue::U8 { value: 55 }],
543            }],
544        })
545        .unwrap();
546        /*
547            91  - prefix
548            32  - value kind: array
549            32  - element value kind: array
550            1   - number of elements: 1
551            7   - element value kind: u8
552            2   - number of elements: u8
553            44  - u8
554            55  - u8
555        */
556        let length = calculate_value_tree_body_byte_length::<NoCustomExtension>(
557            &payload[2..],
558            BasicValueKind::Array,
559            0,
560            100,
561        )
562        .unwrap();
563        assert_eq!(length, 6);
564        let length = calculate_value_tree_body_byte_length::<NoCustomExtension>(
565            &payload[6..],
566            BasicValueKind::U8,
567            0,
568            100,
569        )
570        .unwrap();
571        assert_eq!(length, 1);
572    }
573
574    #[test]
575    pub fn test_exact_events_returned() {
576        let payload = basic_encode(&(
577            2u8,
578            vec![3u8, 7u8],
579            (3u32, indexmap!(16u8 => 18u32)),
580            TestEnum::B(4u32),
581            Vec::<u8>::new(),
582            Vec::<i32>::new(),
583            vec![vec![(-2i64,)]],
584        ))
585        .unwrap();
586
587        let mut traverser = basic_payload_traverser(&payload);
588
589        // Start:
590        next_event_is_container_start_header(
591            &mut traverser,
592            ContainerHeader::Tuple(TupleHeader { length: 7 }),
593            1,
594            1,
595            3,
596        );
597        // First line
598        next_event_is_terminal_value(&mut traverser, TerminalValueRef::U8(2), 2, 3, 5);
599        // Second line
600        next_event_is_container_start_header(
601            &mut traverser,
602            ContainerHeader::Array(ArrayHeader {
603                element_value_kind: ValueKind::U8,
604                length: 2,
605            }),
606            2,
607            5,
608            8,
609        );
610        next_event_is_terminal_value_slice(
611            &mut traverser,
612            TerminalValueBatchRef::U8(&[3u8, 7u8]),
613            3,
614            8,
615            10,
616        );
617        next_event_is_container_end(
618            &mut traverser,
619            ContainerHeader::Array(ArrayHeader {
620                element_value_kind: ValueKind::U8,
621                length: 2,
622            }),
623            2,
624            5,
625            10,
626        );
627        // Third line
628        next_event_is_container_start_header(
629            &mut traverser,
630            ContainerHeader::Tuple(TupleHeader { length: 2 }),
631            2,
632            10,
633            12,
634        );
635        next_event_is_terminal_value(&mut traverser, TerminalValueRef::U32(3), 3, 12, 17);
636        next_event_is_container_start_header(
637            &mut traverser,
638            ContainerHeader::Map(MapHeader {
639                key_value_kind: ValueKind::U8,
640                value_value_kind: ValueKind::U32,
641                length: 1,
642            }),
643            3,
644            17,
645            21,
646        );
647        next_event_is_terminal_value(&mut traverser, TerminalValueRef::U8(16), 4, 21, 22);
648        next_event_is_terminal_value(&mut traverser, TerminalValueRef::U32(18), 4, 22, 26);
649        next_event_is_container_end(
650            &mut traverser,
651            ContainerHeader::Map(MapHeader {
652                key_value_kind: ValueKind::U8,
653                value_value_kind: ValueKind::U32,
654                length: 1,
655            }),
656            3,
657            17,
658            26,
659        );
660        next_event_is_container_end(
661            &mut traverser,
662            ContainerHeader::Tuple(TupleHeader { length: 2 }),
663            2,
664            10,
665            26,
666        );
667        // Fourth line
668        next_event_is_container_start_header(
669            &mut traverser,
670            ContainerHeader::EnumVariant(EnumVariantHeader {
671                variant: 1,
672                length: 1,
673            }),
674            2,
675            26,
676            29,
677        );
678        next_event_is_terminal_value(&mut traverser, TerminalValueRef::U32(4), 3, 29, 34);
679        next_event_is_container_end(
680            &mut traverser,
681            ContainerHeader::EnumVariant(EnumVariantHeader {
682                variant: 1,
683                length: 1,
684            }),
685            2,
686            26,
687            34,
688        );
689        // Fifth line - empty Vec<u8> - no bytes event is output
690        next_event_is_container_start_header(
691            &mut traverser,
692            ContainerHeader::Array(ArrayHeader {
693                element_value_kind: ValueKind::U8,
694                length: 0,
695            }),
696            2,
697            34,
698            37,
699        );
700        next_event_is_container_end(
701            &mut traverser,
702            ContainerHeader::Array(ArrayHeader {
703                element_value_kind: ValueKind::U8,
704                length: 0,
705            }),
706            2,
707            34,
708            37,
709        );
710        // Sixth line - empty Vec<i32>
711        next_event_is_container_start_header(
712            &mut traverser,
713            ContainerHeader::Array(ArrayHeader {
714                element_value_kind: ValueKind::I32,
715                length: 0,
716            }),
717            2,
718            37,
719            40,
720        );
721        next_event_is_container_end(
722            &mut traverser,
723            ContainerHeader::Array(ArrayHeader {
724                element_value_kind: ValueKind::I32,
725                length: 0,
726            }),
727            2,
728            37,
729            40,
730        );
731        // Seventh line - Vec<Vec<(i64)>>
732        next_event_is_container_start_header(
733            &mut traverser,
734            ContainerHeader::Array(ArrayHeader {
735                element_value_kind: ValueKind::Array,
736                length: 1,
737            }),
738            2,
739            40,
740            43,
741        );
742        next_event_is_container_start_header(
743            &mut traverser,
744            ContainerHeader::Array(ArrayHeader {
745                element_value_kind: ValueKind::Tuple,
746                length: 1,
747            }),
748            3,
749            43,
750            45,
751        );
752        next_event_is_container_start_header(
753            &mut traverser,
754            ContainerHeader::Tuple(TupleHeader { length: 1 }),
755            4,
756            45,
757            46,
758        );
759        next_event_is_terminal_value(&mut traverser, TerminalValueRef::I64(-2), 5, 46, 55);
760        next_event_is_container_end(
761            &mut traverser,
762            ContainerHeader::Tuple(TupleHeader { length: 1 }),
763            4,
764            45,
765            55,
766        );
767        next_event_is_container_end(
768            &mut traverser,
769            ContainerHeader::Array(ArrayHeader {
770                element_value_kind: ValueKind::Tuple,
771                length: 1,
772            }),
773            3,
774            43,
775            55,
776        );
777        next_event_is_container_end(
778            &mut traverser,
779            ContainerHeader::Array(ArrayHeader {
780                element_value_kind: ValueKind::Array,
781                length: 1,
782            }),
783            2,
784            40,
785            55,
786        );
787
788        // End
789        next_event_is_container_end(
790            &mut traverser,
791            ContainerHeader::Tuple(TupleHeader { length: 7 }),
792            1,
793            1,
794            55,
795        );
796        next_event_is_end(&mut traverser, 55, 55);
797    }
798
799    pub fn next_event_is_container_start_header(
800        traverser: &mut BasicTraverser,
801        expected_header: ContainerHeader<NoCustomTraversal>,
802        expected_depth: usize,
803        expected_start_offset: usize,
804        expected_end_offset: usize,
805    ) {
806        let event = traverser.next_event();
807        let sbor_depth = event.location.ancestor_path.len() + 1;
808        let LocatedTraversalEvent {
809            event: TraversalEvent::ContainerStart(header),
810            location:
811                Location {
812                    start_offset,
813                    end_offset,
814                    ..
815                },
816        } = event
817        else {
818            panic!("Invalid event - expected ContainerStart, was {:?}", event);
819        };
820        assert_eq!(header, expected_header);
821        assert_eq!(sbor_depth, expected_depth);
822        assert_eq!(start_offset, expected_start_offset);
823        assert_eq!(end_offset, expected_end_offset);
824    }
825
826    pub fn next_event_is_container_end(
827        traverser: &mut BasicTraverser,
828        expected_header: ContainerHeader<NoCustomTraversal>,
829        expected_depth: usize,
830        expected_start_offset: usize,
831        expected_end_offset: usize,
832    ) {
833        let event = traverser.next_event();
834        let sbor_depth = event.location.ancestor_path.len() + 1;
835        let LocatedTraversalEvent {
836            event: TraversalEvent::ContainerEnd(header),
837            location:
838                Location {
839                    start_offset,
840                    end_offset,
841                    ..
842                },
843        } = event
844        else {
845            panic!("Invalid event - expected ContainerEnd, was {:?}", event);
846        };
847        assert_eq!(header, expected_header);
848        assert_eq!(sbor_depth, expected_depth);
849        assert_eq!(start_offset, expected_start_offset);
850        assert_eq!(end_offset, expected_end_offset);
851    }
852
853    pub fn next_event_is_terminal_value<'de>(
854        traverser: &mut BasicTraverser<'de>,
855        expected_value: TerminalValueRef<'de, NoCustomTraversal>,
856        expected_child_depth: usize,
857        expected_start_offset: usize,
858        expected_end_offset: usize,
859    ) {
860        let event = traverser.next_event();
861        let sbor_depth = event.location.ancestor_path.len() + 1;
862        let LocatedTraversalEvent {
863            event: TraversalEvent::TerminalValue(value),
864            location:
865                Location {
866                    start_offset,
867                    end_offset,
868                    ..
869                },
870        } = event
871        else {
872            panic!("Invalid event - expected TerminalValue, was {:?}", event);
873        };
874        assert_eq!(value, expected_value);
875        assert_eq!(sbor_depth, expected_child_depth);
876        assert_eq!(start_offset, expected_start_offset);
877        assert_eq!(end_offset, expected_end_offset);
878    }
879
880    pub fn next_event_is_terminal_value_slice<'de>(
881        traverser: &mut BasicTraverser<'de>,
882        expected_value_batch: TerminalValueBatchRef<'de>,
883        expected_child_depth: usize,
884        expected_start_offset: usize,
885        expected_end_offset: usize,
886    ) {
887        let event = traverser.next_event();
888        let sbor_depth = event.location.ancestor_path.len() + 1;
889        let LocatedTraversalEvent {
890            event: TraversalEvent::TerminalValueBatch(value_batch),
891            location:
892                Location {
893                    start_offset,
894                    end_offset,
895                    ..
896                },
897        } = event
898        else {
899            panic!(
900                "Invalid event - expected TerminalValueBatch, was {:?}",
901                event
902            );
903        };
904        assert_eq!(value_batch, expected_value_batch);
905        assert_eq!(sbor_depth, expected_child_depth);
906        assert_eq!(start_offset, expected_start_offset);
907        assert_eq!(end_offset, expected_end_offset);
908    }
909
910    pub fn next_event_is_end(
911        traverser: &mut BasicTraverser,
912        expected_start_offset: usize,
913        expected_end_offset: usize,
914    ) {
915        let event = traverser.next_event();
916        let LocatedTraversalEvent {
917            event: TraversalEvent::End,
918            location:
919                Location {
920                    start_offset,
921                    end_offset,
922                    ..
923                },
924        } = event
925        else {
926            panic!("Invalid event - expected End, was {:?}", event);
927        };
928        assert_eq!(start_offset, expected_start_offset);
929        assert_eq!(end_offset, expected_end_offset);
930        assert!(event.location.ancestor_path.is_empty());
931    }
932}