Diffstat (limited to 'src/build.rs')
| -rw-r--r-- | src/build.rs | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/src/build.rs b/src/build.rs index f0bb597..b17413a 100644 --- a/src/build.rs +++ b/src/build.rs @@ -24,13 +24,17 @@ pub trait Build<'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>: Default { +pub trait Builder<'ctx> { + type Seed; + /// Error that can happen during filling the builder with data. type Error; /// Type to be built. type Value; + fn from_seed(seed: Self::Seed) -> Self; + /// Get the builder as a visitor that a walker can use. /// /// This is expected to just be `self`. @@ -43,6 +47,19 @@ pub trait Builder<'ctx>: Default { fn build(self) -> Result<Self::Value, Self::Error>; } +pub trait DefaultBuilder<'ctx>: Builder<'ctx> { + fn default() -> Self; +} + +impl<'ctx, B: Builder<'ctx>> DefaultBuilder<'ctx> for B +where + B::Seed: Default, +{ + fn default() -> Self { + Self::from_seed(Default::default()) + } +} + #[derive(Debug)] pub enum BuildError<B, W> { Builder(B), @@ -52,8 +69,11 @@ pub enum BuildError<B, W> { #[inline] pub fn build<'ctx, T: Build<'ctx>, W: Walker<'ctx, Effect = SyncEffect>>( walker: W, -) -> Result<T, BuildError<<<T as Build<'ctx>>::Builder as Builder<'ctx>>::Error, W::Error>> { - let mut builder = T::Builder::default(); +) -> Result<T, BuildError<<<T as Build<'ctx>>::Builder as Builder<'ctx>>::Error, W::Error>> +where + <<T as Build<'ctx>>::Builder as Builder<'ctx>>::Seed: Default, +{ + let mut builder = T::Builder::from_seed(Default::default()); if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor()) { return Err(BuildError::Walker(err)); @@ -64,8 +84,11 @@ pub fn build<'ctx, T: Build<'ctx>, W: Walker<'ctx, Effect = SyncEffect>>( pub fn build_with<'ctx, B: Builder<'ctx>, W: Walker<'ctx, Effect = SyncEffect>>( walker: W, -) -> Result<B::Value, BuildError<B::Error, W::Error>> { - let mut builder = B::default(); +) -> Result<B::Value, BuildError<B::Error, W::Error>> +where + <B as Builder<'ctx>>::Seed: Default, +{ + let mut builder = B::from_seed(Default::default()); if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor()) { return Err(BuildError::Walker(err)); @@ -78,7 +101,11 @@ pub fn build_with<'ctx, B: Builder<'ctx>, W: Walker<'ctx, Effect = SyncEffect>>( use crate::protocol::AsyncEffect; #[cfg(feature = "alloc")] -pub async fn async_build_with<'ctx, B: Builder<'ctx>, W: Walker<'ctx, Effect = AsyncEffect>>( +pub async fn async_build_with< + 'ctx, + B: DefaultBuilder<'ctx>, + W: Walker<'ctx, Effect = AsyncEffect>, +>( walker: W, ) -> Result<B::Value, BuildError<B::Error, W::Error>> { let mut builder = B::default(); |