1use super::*;
2use crate::decoder::BorrowingDecoder;
3use crate::rust::prelude::*;
4use crate::rust::str;
5use crate::value_kind::*;
6use crate::*;
7
8pub 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 pub container_start_offset: usize,
58 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
74pub 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 ReadNextChildOrExitContainer,
106 Errored,
107 Ended,
108 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 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 let start_offset = decoder.get_offset();
167 match decoder.read_and_check_payload_prefix(expected_prefix) {
168 Ok(()) => {
169 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 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 ancestor_path.push(AncestorState {
205 container_header,
206 container_start_offset,
207 current_child_index: 0,
208 });
209 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 is_byte_array {
228 let array_length = container_child_size;
230 let max_index_which_would_be_read = array_length - 1;
231 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 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 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 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
304struct 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 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 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 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 next_event_is_container_start_header(
591 &mut traverser,
592 ContainerHeader::Tuple(TupleHeader { length: 7 }),
593 1,
594 1,
595 3,
596 );
597 next_event_is_terminal_value(&mut traverser, TerminalValueRef::U8(2), 2, 3, 5);
599 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 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 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 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 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 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 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}