Diffstat (limited to 'src/macros.rs')
| -rw-r--r-- | src/macros.rs | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/src/macros.rs b/src/macros.rs index a946257..ffb52b1 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -9,47 +9,51 @@ use crate::{ }; #[derive(Debug)] -pub struct TagError { - symbol: Symbol, - msg: &'static str, +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), } -impl From<TagError> for &'static str { - fn from(value: TagError) -> Self { - value.msg - } +#[derive(Debug)] +pub struct TagError<E> { + symbol: Symbol, + err: TagErrorKind<E>, } -impl TagError { - fn new<const SYMBOL: u64>(msg: &'static str) -> Self { +impl<E> TagError<E> { + fn new<const SYMBOL: u64>(err: E) -> Self { Self { symbol: Symbol::from_int(SYMBOL), - msg, + err: TagErrorKind::Walker(err), } } fn never_walked<const SYMBOL: u64>() -> Self { - Self::new::<SYMBOL>("visitor did not walk the walker") + Self { + symbol: Symbol::from_int(SYMBOL), + err: TagErrorKind::NeverWalked, + } } fn walk_never_finished<const SYMBOL: u64>() -> Self { - Self::new::<SYMBOL>("walk did not finish") + 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, Effect = E> + 'a, ->( +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, Flow<TagError>, E> +) -> Future<'a, 'ctx, Result<Flow, TagError<W::Error>>, E> where W: WalkerTypes<Output = ()>, - <W as WalkerTypes>::Error: Into<&'static str>, { E::wrap(async { let result = @@ -89,32 +93,28 @@ where let Some(result) = result else { // The visitor doesn't know about this tag protocol so just continue as normal. - return Flow::Continue; + return Ok(Flow::Continue); }; match result { // The happy path. - (Flow::Continue, Ok(_)) => Flow::Continue, + (Flow::Continue, Ok(_)) => Ok(Flow::Continue), // The visitor wants to stop the control flow for some reason. - (Flow::Break, Ok(_)) => Flow::Break, + (Flow::Break, Ok(_)) => Ok(Flow::Break), + (Flow::Done, Ok(_)) => Ok(Flow::Done), // The walker had an error. - (_, Err(DynWalkerError::Walker(err))) => Flow::Err(TagError::new::<SYMBOL>(err.into())), + (_, 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(_))) => { - Flow::Err(TagError::never_walked::<SYMBOL>()) - } + (_, 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)) => { - Flow::Err(TagError::walk_never_finished::<SYMBOL>()) + Err(TagError::walk_never_finished::<SYMBOL>()) } - - // This isn't possible because Err(!). - (Flow::Err(_), _) => unreachable!(), } }) } |