Diffstat (limited to 'src/build.rs')
| -rw-r--r-- | src/build.rs | 63 |
1 files changed, 33 insertions, 30 deletions
diff --git a/src/build.rs b/src/build.rs index 72f395d..b75fa6b 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,12 +1,12 @@ pub mod builders; use crate::{ - protocol::{AnyTraitSendObj as _, Effect, SyncEffect, Visitor}, + protocol::{AsObj as _, Effect, EffectAnyTrait, SyncEffect, Visitor, Yield}, Walker, }; /// A buildable type. -pub trait Build<'ctx, E: Effect<'ctx>>: Sized { +pub trait Build<'ctx, E: EffectAnyTrait<'ctx>>: Sized { /// The builder that can be used to build a value of `Self`. type Builder: Builder<'ctx, E, Value = Self>; } @@ -24,7 +24,9 @@ pub trait Build<'ctx, E: Effect<'ctx>>: Sized { /// the builder with data from it's walk. /// - Call [`Self::build()`] to finish building the value and get any errors /// that happened during filling it with data. -pub trait Builder<'ctx, E: Effect<'ctx>>: AsVisitor<'ctx, E> { +pub trait Builder<'ctx, E: EffectAnyTrait<'ctx>>: AsVisitor<'ctx, E> { + type Effect: Effect<'ctx, Result<Self::Value, Self::Error>>; + type Seed; /// Error that can happen during filling the builder with data. @@ -39,21 +41,21 @@ pub trait Builder<'ctx, E: Effect<'ctx>>: AsVisitor<'ctx, E> { /// /// If an error happened with the builder during the walk /// it will be reported here. - fn build(self) -> Result<Self::Value, Self::Error>; + fn build<'a>(self) -> Yield<'a, 'ctx, Result<Self::Value, Self::Error>, Self::Effect> where Self: 'a; } -pub trait AsVisitor<'ctx, E: Effect<'ctx>> { +pub trait AsVisitor<'ctx, E: EffectAnyTrait<'ctx>> { /// Get the builder as a visitor that a walker can use. /// /// This is expected to just be `self`. fn as_visitor(&mut self) -> Visitor<'_, 'ctx, E>; } -pub trait DefaultBuilder<'ctx, E: Effect<'ctx>>: Builder<'ctx, E> { +pub trait DefaultBuilder<'ctx, E: EffectAnyTrait<'ctx>>: Builder<'ctx, E> { fn default() -> Self; } -impl<'ctx, B: Builder<'ctx, E>, E: Effect<'ctx>> DefaultBuilder<'ctx, E> for B +impl<'ctx, B: Builder<'ctx, E>, E: EffectAnyTrait<'ctx>> DefaultBuilder<'ctx, E> for B where B::Seed: Default, { @@ -68,29 +70,30 @@ pub enum BuildError<B, W> { Walker(W), } -// #[inline] -// pub fn build<'ctx, T: Build<'ctx, SyncEffect>, W: for<'a> Walker<'a, 'ctx, Effect = SyncEffect>>( -// walker: W, -// ) -> Result< -// T, -// BuildError< -// <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Error, -// W::Error, -// >, -// > -// where -// <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Seed: Default, -// { -// let mut builder = T::Builder::from_seed(Default::default()); -// -// if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor().as_obj_mut()) { -// return Err(BuildError::Walker(err)); -// } -// -// builder.build().map_err(BuildError::Builder) -// } +#[inline] +pub fn build<'ctx, T: Build<'ctx, SyncEffect>, W: Walker<'ctx, Effect = SyncEffect>>( + walker: W, +) -> Result< + T, + BuildError< + <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Error, + W::Error, + >, +> +where + <T as Build<'ctx, SyncEffect>>::Builder: Builder<'ctx, SyncEffect, Effect = SyncEffect>, + <<T as Build<'ctx, SyncEffect>>::Builder as Builder<'ctx, SyncEffect>>::Seed: Default, +{ + let mut builder = T::Builder::from_seed(Default::default()); + + if let Err(err) = walker.walk(builder.as_visitor().as_obj_mut()) { + return Err(BuildError::Walker(err)); + } + + builder.build().map_err(BuildError::Builder) +} -pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect>, W: Walker<'ctx, Effect = SyncEffect>>( +pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect, Effect = SyncEffect>, W: Walker<'ctx, Effect = SyncEffect>>( walker: W, ) -> Result<B::Value, BuildError<B::Error, W::Error>> where @@ -98,7 +101,7 @@ where { let mut builder = B::from_seed(Default::default()); - if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor().as_obj_mut()) { + if let Err(err) = walker.walk(builder.as_visitor().as_obj_mut()) { return Err(BuildError::Walker(err)); } |