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 { type Seed: DynBind; /// Error that can happen during filling the builder with data. type Error: DynBind + Debug + Display; type Output: DynBind; /// 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 + AsVisitor<'src, E> + BuilderTypes + 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, E> where Self: 'u; }