Diffstat (limited to 'src/macros.rs')
| -rw-r--r-- | src/macros.rs | 120 |
1 files changed, 0 insertions, 120 deletions
diff --git a/src/macros.rs b/src/macros.rs index ffb52b1..e69de29 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,120 +0,0 @@ -use crate::{ - effect::{Effect, Future}, - protocol::{ - visitor::tag::{self, DynTag}, - Visitor, - }, - symbol::Symbol, - DynWalkerAdapter, DynWalkerError, Flow, Walker, WalkerTypes, -}; - -#[derive(Debug)] -pub enum TagErrorKind<E> { - NeverWalked, - - /// This can only happen if a panic happens furing the walk and is then caught before calling - /// finish.. - WalkNeverFinished, - - Walker(E), -} - -#[derive(Debug)] -pub struct TagError<E> { - symbol: Symbol, - err: TagErrorKind<E>, -} - -impl<E> TagError<E> { - fn new<const SYMBOL: u64>(err: E) -> Self { - Self { - symbol: Symbol::from_int(SYMBOL), - err: TagErrorKind::Walker(err), - } - } - - fn never_walked<const SYMBOL: u64>() -> Self { - Self { - symbol: Symbol::from_int(SYMBOL), - err: TagErrorKind::NeverWalked, - } - } - - fn walk_never_finished<const SYMBOL: u64>() -> Self { - Self { - symbol: Symbol::from_int(SYMBOL), - err: TagErrorKind::WalkNeverFinished, - } - } -} - -pub fn visit_tag<'a, 'ctx: 'a, const SYMBOL: u64, E: Effect<'ctx>, W: Walker<'ctx, E> + 'a>( - visitor: Visitor<'a, 'ctx>, - walker: W, -) -> Future<'a, 'ctx, Result<Flow, TagError<W::Error>>, E> -where - W: WalkerTypes<Output = ()>, -{ - E::wrap(async { - let result = - if let Some(object) = visitor.upcast_mut::<DynTag<'_, 'ctx, tag::Const<SYMBOL>, E>>() { - // The visitor knows about this tag at compile time. - - // Wrap the walker to allow it to be passed to a dyn walker argument. - let mut name_walker = DynWalkerAdapter::new(walker); - - // Visit the tag. - let flow = object.visit(tag::Const, &mut name_walker).await; - - // Finish the dynamic walker to get any errors from it. - let result = name_walker.finish(); - - Some((flow, result)) - } else if let Some(object) = visitor.upcast_mut::<DynTag<'_, 'ctx, tag::Dyn, E>>() { - // The visitor can handle dynamic tags. - // If the visitor can't handle the tag kind then it can call .skip on the walker - // to disable the error for not walking it. - - // Wrap the walker to allow it to be passed to a dyn walker argument. - let mut name_walker = DynWalkerAdapter::new(walker); - - // Visit the tag. - let flow = object - .visit(tag::Dyn(Symbol::from_int(SYMBOL)), &mut name_walker) - .await; - - // Finish the dynamic walker to get any errors from it. - let result = name_walker.finish(); - - Some((flow, result)) - } else { - None - }; - - let Some(result) = result else { - // The visitor doesn't know about this tag protocol so just continue as normal. - return Ok(Flow::Continue); - }; - - match result { - // The happy path. - (Flow::Continue, Ok(_)) => Ok(Flow::Continue), - - // The visitor wants to stop the control flow for some reason. - (Flow::Break, Ok(_)) => Ok(Flow::Break), - (Flow::Done, Ok(_)) => Ok(Flow::Done), - - // The walker had an error. - (_, Err(DynWalkerError::Walker(err))) => Err(TagError::new::<SYMBOL>(err)), - - // The visitor never walked the dynamic walker. Aka it didn't call walk. - (_, Err(DynWalkerError::NeverWalked(_))) => Err(TagError::never_walked::<SYMBOL>()), - - // This is very hard to cause. The visitor must panic inside of .walk but then - // catch it in .visit. - (_, Err(DynWalkerError::WalkNeverFinished)) => { - Err(TagError::walk_never_finished::<SYMBOL>()) - } - } - }) -} |