use core::fmt::{Debug, Display};
pub mod builders;
use effectful::{bound::SsBound, effective::Canonical, environment::Environment, DynBind};
use crate::protocol::AsVisitor;
/// The canonical builders for a type.
///
/// This trait associates a set of builders with the type.
/// This trait is mainly used by the derive macros to automatically select a builder
/// for a field or variant.
///
/// There can be one canonical builder per mode. The mode is specified by the `M` generic and
/// can be any type. It is only used as a type level tag.
pub trait Build<'src, M, E: Environment>: Sized {
/// The canonical builder for mode `M`.
///
/// This builder will build values of type `Self`.
type Builder: Builder<'src, E, Value = Self>;
}
pub trait BuilderTypes<C: SsBound> {
type Seed: DynBind<C>;
/// Error that can happen during filling the builder with data.
type Error: DynBind<C> + Debug + Display;
type Output: DynBind<C>;
/// Type to be built.
type Value;
fn unwrap_output(output: Self::Output) -> Self::Value;
}
/// 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`][BuilderTypes::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<'src, E: Environment>:
DynBind<E> + AsVisitor<'src, E> + BuilderTypes<E> + Sized
{
fn from_seed<'u>(seed: Self::Seed) -> Canonical<'u, Self, E>
where
Self: 'u;
/// Finish the value.
///
/// If an error happened with the builder during the walk
/// it will be reported here.
fn build<'u>(self) -> Canonical<'u, Result<Self::Output, Self::Error>, E>
where
Self: 'u;
}