Diffstat (limited to 'src/build.rs')
-rw-r--r--src/build.rs39
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();