// pub mod builders;
use crate::{
protocol::{AnyTraitSendObj as _, Effect, SyncEffect, Visitor},
Walker,
};
/// A buildable type.
pub trait Build<'ctx, E: Effect<'ctx>>: Sized {
/// The builder that can be used to build a value of `Self`.
type Builder: Builder<'ctx, E, Value = Self>;
}
/// Builder for a type.
///
/// The `'ctx` lifetime is some lifetime that is longer than the walker.
/// As such, the built value can borrow from other data with a `'ctx` lifetimes.
///
/// A builder allows creating a value of a type [`Self::Value`].
/// The way to use a builder is as follows.
/// - Call [`Default::default()`] to create an instance of the builder.
/// - Call [`Self::as_visitor()`] and give it to a walker's
/// [`walk()`][crate::walk::Walker::walk]. The walker will then fill
/// 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> {
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;
/// Finish the value.
///
/// If an error happened with the builder during the walk
/// it will be reported here.
fn build(self) -> Result<Self::Value, Self::Error>;
}
pub trait AsVisitor<'ctx, E: Effect<'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> {
fn default() -> Self;
}
impl<'ctx, B: Builder<'ctx, E>, E: Effect<'ctx>> DefaultBuilder<'ctx, E> for B
where
B::Seed: Default,
{
fn default() -> Self {
Self::from_seed(Default::default())
}
}
#[derive(Debug)]
pub enum BuildError<B, W> {
Builder(B),
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)
// }
//
// pub fn build_with<'ctx, B: Builder<'ctx, SyncEffect>, W: for<'a> Walker<'a, 'ctx, Effect = SyncEffect>>(
// walker: W,
// ) -> Result<B::Value, BuildError<B::Error, W::Error>>
// where
// <B as Builder<'ctx, SyncEffect>>::Seed: Default,
// {
// let mut builder = B::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)
// }
// #[cfg(feature = "alloc")]
// use crate::protocol::AsyncEffect;
//
// #[cfg(feature = "alloc")]
// pub async fn async_build_with<
// 'ctx,
// B: DefaultBuilder<'ctx, AsyncEffect>,
// W: for<'a> Walker<'a, 'ctx, Effect = AsyncEffect>,
// >(
// walker: W,
// ) -> Result<B::Value, BuildError<B::Error, W::Error>> {
// let mut builder = B::default();
//
// if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor()).await {
// return Err(BuildError::Walker(err));
// }
//
// builder.build().map_err(BuildError::Builder)
// }