Skip to content

Commit

Permalink
tweak: Move some code around
Browse files Browse the repository at this point in the history
  • Loading branch information
dhedey committed Sep 25, 2024
1 parent ae4c431 commit 0d63ac4
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 7 deletions.
1 change: 1 addition & 0 deletions radix-common/src/data/scrypto/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub type ScryptoEncoder<'a> = VecEncoder<'a, ScryptoCustomValueKind>;
pub type ScryptoDecoder<'a> = VecDecoder<'a, ScryptoCustomValueKind>;
#[allow(deprecated)]
pub type ScryptoTraverser<'a> = VecTraverser<'a, ScryptoCustomTraversal>;
pub type ScryptoUntypedTraverser<'a> = UntypedTraverser<'a, ScryptoCustomTraversal>;
pub type ScryptoValueKind = ValueKind<ScryptoCustomValueKind>;
pub type ScryptoValue = Value<ScryptoCustomValueKind, ScryptoCustomValue>;
// ScryptoRawValue and friends are defined in custom_payload_wrappers.rs
Expand Down
1 change: 1 addition & 0 deletions sbor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ pub(crate) mod internal_prelude {
// These are mostly used for more advanced use cases,
// so aren't included in the general prelude
pub use crate::basic::*;
pub use crate::basic_well_known_types::*;
pub use crate::decoder::*;
pub use crate::encoder::*;
pub use crate::payload_validation::*;
Expand Down
2 changes: 2 additions & 0 deletions sbor/src/traversal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
mod path_formatting;
mod traversal_traits;
mod typed;
mod untyped;

pub use path_formatting::*;
pub use traversal_traits::*;
pub use typed::*;
pub use untyped::*;
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,83 @@ pub struct OnError<'t, T: CustomTraversal> {
pub error: DecodeError,
pub location: Location<'t, T>,
}

// We add this allow so that the placeholder names don't have to start with underscores
#[allow(unused_variables)]
pub trait TypedPayloadVisitor<'de, E: CustomExtension> {
type Output<'t, 's>
where
's: 't;

#[inline]
#[must_use]
fn on_container_start<'t, 's>(
&mut self,
details: OnContainerStartTyped<'t, 's, E::CustomTraversal>,
) -> ControlFlow<Self::Output<'t, 's>> {
ControlFlow::Continue(())
}

#[inline]
#[must_use]
fn on_terminal_value<'t, 's>(
&mut self,
details: OnTerminalValueTyped<'t, 's, 'de, E::CustomTraversal>,
) -> ControlFlow<Self::Output<'t, 's>> {
ControlFlow::Continue(())
}

#[inline]
#[must_use]
fn on_terminal_value_batch<'t, 's>(
&mut self,
details: OnTerminalValueBatchTyped<'t, 's, 'de, E::CustomTraversal>,
) -> ControlFlow<Self::Output<'t, 's>> {
ControlFlow::Continue(())
}

#[inline]
#[must_use]
fn on_container_end<'t, 's>(
&mut self,
details: OnContainerEndTyped<'t, 's, E::CustomTraversal>,
) -> ControlFlow<Self::Output<'t, 's>> {
ControlFlow::Continue(())
}

#[must_use]
fn on_error<'t, 's>(&mut self, details: OnErrorTyped<'t, 's, E>) -> Self::Output<'t, 's>;

#[must_use]
fn on_traversal_end<'t, 's>(&mut self, details: OnTraversalEndTyped) -> Self::Output<'t, 's>;
}

pub struct OnContainerStartTyped<'t, 's, T: CustomTraversal> {
pub local_type_id: LocalTypeId,
pub header: ContainerHeader<T>,
pub location: TypedLocation<'t, 's, T>,
}

pub struct OnTerminalValueTyped<'t, 's, 'de, T: CustomTraversal> {
pub local_type_id: LocalTypeId,
pub value: TerminalValueRef<'de, T>,
pub location: TypedLocation<'t, 's, T>,
}

pub struct OnTerminalValueBatchTyped<'t, 's, 'de, T: CustomTraversal> {
pub local_type_id: LocalTypeId,
pub value_batch: TerminalValueBatchRef<'de>,
pub location: TypedLocation<'t, 's, T>,
}

pub struct OnContainerEndTyped<'t, 's, T: CustomTraversal> {
pub local_type_id: LocalTypeId,
pub location: TypedLocation<'t, 's, T>,
}

pub struct OnTraversalEndTyped {}

pub struct OnErrorTyped<'t, 's, E: CustomExtension> {
pub error: TypedTraversalError<E>,
pub location: TypedLocation<'t, 's, E::CustomTraversal>,
}
66 changes: 61 additions & 5 deletions sbor/src/traversal/typed/typed_traverser.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use super::*;
use crate::basic_well_known_types::ANY_TYPE;
use crate::rust::prelude::*;
use crate::traversal::*;
use crate::*;
use crate::internal_prelude::*;

pub fn traverse_payload_with_types<'de, 's, E: CustomExtension>(
payload: &'de [u8],
Expand Down Expand Up @@ -142,6 +138,66 @@ impl<'de, 's, E: CustomExtension> TypedTraverser<'de, 's, E> {
}
}

/// Allows migrating off `next_event` before it's removed
pub fn traverse<'t, V: TypedPayloadVisitor<'de, E>>(
&'t mut self,
visitor: &mut V,
) -> V::Output<'t, 's> {
match self.traverse_internal(visitor) {
ControlFlow::Continue(_) => unreachable!("Never returns a continue"),
ControlFlow::Break(output) => output,
}
}

fn traverse_internal<'t, V: TypedPayloadVisitor<'de, E>>(
&'t mut self,
visitor: &mut V,
) -> ControlFlow<V::Output<'t, 's>> {
loop {
// SAFETY: Work around the current borrow checker, which is sound as per this thread:
// https://users.rust-lang.org/t/mutable-borrow-in-loop-borrow-checker-query/118081/3
// Unsafe syntax borrowed from here: https://docs.rs/polonius-the-crab/latest/polonius_the_crab/
// Can remove this once the polonius borrow checker hits stable
let fixed_self: &mut TypedTraverser<'de, 's, E> = unsafe { &mut *(self as *mut _) };
let TypedLocatedTraversalEvent { location, event } = fixed_self.next_event();
match event {
TypedTraversalEvent::ContainerStart(local_type_id, header) => {
visitor.on_container_start(OnContainerStartTyped {
local_type_id,
header,
location,
})?;
}
TypedTraversalEvent::ContainerEnd(local_type_id, _header) => {
visitor.on_container_end(OnContainerEndTyped {
local_type_id,
location,
})?;
}
TypedTraversalEvent::TerminalValue(local_type_id, value) => {
visitor.on_terminal_value(OnTerminalValueTyped {
local_type_id,
value,
location,
})?;
}
TypedTraversalEvent::TerminalValueBatch(local_type_id, value_batch) => {
visitor.on_terminal_value_batch(OnTerminalValueBatchTyped {
local_type_id,
value_batch,
location,
})?;
}
TypedTraversalEvent::Error(error) => {
ControlFlow::Break(visitor.on_error(OnErrorTyped { error, location }))?;
}
TypedTraversalEvent::End => {
ControlFlow::Break(visitor.on_traversal_end(OnTraversalEndTyped {}))?;
}
}
}
}

pub fn next_event(&mut self) -> TypedLocatedTraversalEvent<'_, 's, 'de, E> {
let (typed_event, location) =
Self::next_event_internal(&mut self.traverser, &mut self.state);
Expand Down
2 changes: 0 additions & 2 deletions sbor/src/traversal/untyped/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ use crate::internal_prelude::*;

mod event_stream_traverser;
mod events;
mod traversal_traits;
mod untyped_traverser;
mod utility_visitors;

pub use event_stream_traverser::*;
pub use events::*;
pub use traversal_traits::*;
pub use untyped_traverser::*;
pub use utility_visitors::*;

Expand Down

0 comments on commit 0d63ac4

Please sign in to comment.