use core::fmt::Display;
use effectful::{
bound::Dynamic,
effective::{Effective, Canonical},
environment::{Environment},
DynBind,
SendSync,
};
use crate::{
any::{
type_name, AnyTrait, BorrowedMutStatic, BorrowedStatic, OwnedStatic, TempBorrowedMutStatic,
TempBorrowedStatic,
},
hkt::Marker,
protocol::{
visitor::{EffectiveVisitExt as _, RequestHint, Value, VisitResult},
walker::hint::hint_protocol,
AsVisitor, DynVisitor, DynWalker,
},
trait_by_id, Flow,
};
#[derive(SendSync)]
#[non_exhaustive]
pub struct ValueError<T>(Marker<T>);
impl<T> ::core::fmt::Debug for ValueError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "missing value of type `{}`", core::any::type_name::<T>())
}
}
impl<T> Display for ValueError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "missing value of type `{}`", core::any::type_name::<T>())
}
}
pub enum Cloneable {}
pub enum NotCloneable {}
/// Builder for `'static` values.
///
/// This builder only uses the [`Value`] protocol.
///
#[doc = crate::doc_macro::mermaid!("value.mmd", 100)]
///
/// After
#[derive(SendSync)]
pub struct ValueBuilder<T, Clone, E> {
value: Option<Dynamic<T>>,
_marker: Marker<(E, Clone)>,
}
impl<T, Clone, E: Environment> crate::build::BuilderTypes<E> for ValueBuilder<T, Clone, E>
where
Dynamic<T>: DynBind<E>,
{
type Error = ValueError<T>;
type Output = Dynamic<T>;
type Value = T;
type Seed = ();
fn unwrap_output(output: Self::Output) -> Self::Value {
output.0
}
}
impl<'lt, 'ctx: 'lt, T: 'static, Clone, E: Environment> crate::Builder<'lt, 'ctx, E> for ValueBuilder<T, Clone, E>
where
Dynamic<T>: DynBind<E>,
Self: AnyTrait<'lt, 'ctx>,
{
fn build<'a>(self) -> Canonical<'a, Result<Self::Output, Self::Error>, E>
where
Self: 'a,
{
E::value(self.value.ok_or(ValueError(Default::default()))).cast()
}
fn from_seed<'a>(_seed: Self::Seed) -> Canonical<'a, Self, E>
where
Self: 'a,
{
E::value(Self {
value: None,
_marker: Default::default(),
})
.cast()
}
}
impl<'lt, 'ctx: 'lt, T: 'static, Clone, E: Environment> AsVisitor<'lt, 'ctx, E> for ValueBuilder<T, Clone, E>
where
Self: AnyTrait<'lt, 'ctx> + DynBind<E>,
{
fn as_visitor<'a>(&'a mut self) -> DynVisitor<'a, 'lt, 'ctx, E> {
DynVisitor(self)
}
}
impl<'lt, 'ctx: 'lt, T: 'static, E: Environment> AnyTrait<'lt, 'ctx> for ValueBuilder<T, NotCloneable, E>
where
Dynamic<T>: DynBind<E>,
for<'a> Dynamic<&'a T>: DynBind<E>,
Dynamic<OwnedStatic<T>>: DynBind<E>,
for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>,
{
fn upcast_by_id_mut<'a>(
&'a mut self,
id: crate::any::WithLtTypeId<'lt, 'ctx>,
) -> Option<crate::any::MutAnyUnsized<'a, 'lt, 'ctx>>
where
'lt: 'a
{
trait_by_id!(&mut self, id, {
type Impls = (dyn RequestHint<'ctx, E>, dyn Value<'ctx, OwnedStatic<T>, E>);
});
None
}
}
impl<'lt, 'ctx: 'lt, T: 'static + Clone, E: Environment> AnyTrait<'lt, 'ctx> for ValueBuilder<T, Cloneable, E>
where
Dynamic<T>: DynBind<E>,
for<'a> Dynamic<&'a T>: DynBind<E>,
for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>,
Dynamic<OwnedStatic<T>>: DynBind<E>,
Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>,
for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, T>>: DynBind<E>,
for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>,
for<'a> Dynamic<&'a TempBorrowedStatic<'a, T>>: DynBind<E>,
Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>,
for<'a, 'b> Dynamic<&'a BorrowedMutStatic<'b, T>>: DynBind<E>,
for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>,
for<'a> Dynamic<&'a TempBorrowedMutStatic<'a, T>>: DynBind<E>,
{
fn upcast_by_id_mut<'a>(
&'a mut self,
id: crate::any::WithLtTypeId<'lt, 'ctx>,
) -> Option<crate::any::MutAnyUnsized<'a, 'lt, 'ctx>>
where
'lt: 'a,
{
dbg!(&id);
trait_by_id!(&mut self, id, {
type Impls = (dyn RequestHint<'ctx, E>, dyn Value<'ctx, OwnedStatic<T>, E>);
});
None
}
}
// any_trait! {
// impl['ctx, T][E] ValueBuilder<T, NotCloneable, E> = [
// RequestHintProto<E>,
// ValueProto<OwnedStatic<T>, E>,
// ] where
// E: Environment,
// T: 'static,
// Dynamic<T>: DynBind<E>,
// for<'a> Dynamic<&'a T>: DynBind<E>,
// Dynamic<OwnedStatic<T>>: DynBind<E>,
// for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>,
// }
//
// any_trait! {
// impl['ctx, T][E] ValueBuilder<T, Cloneable, E> = [
// RequestHintProto<E>,
// ValueProto<OwnedStatic<T>, E>,
// ValueProto<BorrowedStaticHrt<T>, E>,
// ValueProto<TempBorrowedStaticHrt<T>, E>,
// ValueProto<BorrowedMutStaticHrt<T>, E>,
// ValueProto<TempBorrowedMutStaticHrt<T>, E>,
// ] where
// E: Environment,
// T: 'static + Clone,
// Dynamic<T>: DynBind<E>,
// for<'a> Dynamic<&'a T>: DynBind<E>,
// for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>,
// Dynamic<OwnedStatic<T>>: DynBind<E>,
// Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>,
// for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, T>>: DynBind<E>,
// for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>,
// for<'a> Dynamic<&'a TempBorrowedStatic<'a, T>>: DynBind<E>,
// Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>,
// for<'a, 'b> Dynamic<&'a BorrowedMutStatic<'b, T>>: DynBind<E>,
// for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>,
// for<'a> Dynamic<&'a TempBorrowedMutStatic<'a, T>>: DynBind<E>,
// }
impl<'ctx, T: 'static, E: Environment> RequestHint<'ctx, E> for ValueBuilder<T, NotCloneable, E>
where
Dynamic<T>: DynBind<E>,
for<'a> Dynamic<&'a T>: DynBind<E>,
Dynamic<OwnedStatic<T>>: DynBind<E>,
for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>,
{
fn request_hint<'this: 'e, 'walker: 'e, 'lt: 'e, 'e>(
&'this mut self,
walker: DynWalker<'walker, 'lt, 'ctx, E>,
) -> Canonical<'e, VisitResult, E>
where
'ctx: 'this + 'walker,
{
E::value((self, walker))
.update_map((), |_, (this, walker)| {
hint_protocol::<dyn Value<'_, OwnedStatic<T>, E>, _, _>(walker.cast(), *this, ()).cast()
})
.map((), |_, (_, x)| x)
.cast()
}
}
impl<'ctx, T: 'static, E: Environment> RequestHint<'ctx, E> for ValueBuilder<T, Cloneable, E>
where
T: Clone,
Dynamic<T>: DynBind<E>,
for<'a> Dynamic<&'a T>: DynBind<E>,
Dynamic<OwnedStatic<T>>: DynBind<E>,
for<'a> Dynamic<&'a OwnedStatic<T>>: DynBind<E>,
Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>,
for<'a, 'b> Dynamic<&'a BorrowedStatic<'b, T>>: DynBind<E>,
for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>,
for<'a> Dynamic<&'a TempBorrowedStatic<'a, T>>: DynBind<E>,
Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>,
for<'a, 'b> Dynamic<&'a BorrowedMutStatic<'b, T>>: DynBind<E>,
for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>,
for<'a> Dynamic<&'a TempBorrowedMutStatic<'a, T>>: DynBind<E>,
{
fn request_hint<'this: 'e, 'walker: 'e, 'lt: 'e, 'e>(
&'this mut self,
walker: DynWalker<'walker, 'lt, 'ctx, E>,
) -> Canonical<'e, VisitResult, E>
where
'ctx: 'this + 'walker,
{
E::value((self, walker))
.update_map((), |_, (this, walker)| {
hint_protocol::<dyn Value<'_, OwnedStatic<T>, E>, _, _>(walker.cast(), *this, ())
.cast()
})
.cast::<()>()
.if_not_finished((), |_, (this, walker)| {
hint_protocol::<
dyn Value<'_, type_name::Raised<'_, '_, BorrowedStatic<'_, T>>, E>,
_,
_,
>(walker.cast(), *this, ())
.cast()
})
.cast::<()>()
.if_not_finished((), |_, (this, walker)| {
hint_protocol::<
dyn Value<'_, type_name::Raised<'_, '_, TempBorrowedStatic<'_, T>>, E>,
_,
_,
>(walker.cast(), *this, ())
.cast()
})
.cast::<()>()
.if_not_finished((), |_, (this, walker)| {
hint_protocol::<
dyn Value<'_, type_name::Raised<'_, '_, BorrowedMutStatic<'_, T>>, E>,
_,
_,
>(walker.cast(), *this, ())
.cast()
})
.cast::<()>()
.if_not_finished((), |_, (this, walker)| {
hint_protocol::<
dyn Value<'_, type_name::Raised<'_, '_, TempBorrowedMutStatic<'_, T>>, E>,
_,
_,
>(walker.cast(), *this, ())
.cast()
})
.map((), |_, (_, x)| x)
.cast()
}
}
impl<'ctx, T: 'static, Clone, E: Environment> Value<'ctx, OwnedStatic<T>, E>
for ValueBuilder<T, Clone, E>
where
Dynamic<T>: DynBind<E>,
Dynamic<OwnedStatic<T>>: DynBind<E>,
{
fn visit<'this: 'value, 'value: 'e, 'e>(
&'this mut self,
value: type_name::Lowered<'value, 'ctx, OwnedStatic<T>>,
) -> Canonical<'e, VisitResult<Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<T>>>>, E>
where
type_name::Lowered<'value, 'ctx, OwnedStatic<T>>: Sized,
Dynamic<type_name::Lowered<'value, 'ctx, OwnedStatic<T>>>: DynBind<E>,
'ctx: 'this + 'value,
{
self.value = Some(Dynamic(value.0));
E::value(Flow::Done.into()).cast()
}
}
impl<'ctx, T: 'static, E: Environment>
Value<'ctx, type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>, E>
for ValueBuilder<T, Cloneable, E>
where
T: Clone,
Dynamic<T>: DynBind<E>,
Dynamic<BorrowedStatic<'ctx, T>>: DynBind<E>,
{
fn visit<'this: 'value, 'value: 'e, 'e>(
&'this mut self,
value: type_name::Lowered<
'value,
'ctx,
type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>,
>,
) -> Canonical<
'e,
VisitResult<
Dynamic<
type_name::Lowered<
'value,
'ctx,
type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>,
>,
>,
>,
E,
>
where
type_name::Lowered<'value, 'ctx, type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>>:
Sized,
Dynamic<
type_name::Lowered<
'value,
'ctx,
type_name::Raised<'static, 'ctx, BorrowedStatic<'ctx, T>>,
>,
>: DynBind<E>,
'ctx: 'this + 'value,
{
self.value = Some(Dynamic(value.0.clone()));
E::value(Flow::Done.into()).cast()
}
}
// impl<'ctx, T: 'static, E: Environment>
// Value<'ctx, type_name::Raised<'static, 'ctx, TempBorrowedStatic<'static, T>>, E>
// for ValueBuilder<T, Cloneable, E>
// where
// T: Clone,
// Dynamic<T>: DynBind<E>,
// for<'a> Dynamic<TempBorrowedStatic<'a, T>>: DynBind<E>,
// {
// fn visit<'a>(
// &'a mut self,
// TempBorrowedStatic(value): TempBorrowedStatic<'a, T>,
// ) -> Canonical<'a, VisitResult<Dynamic<TempBorrowedStatic<'a, T>>>, E>
// where
// 'ctx: 'a,
// {
// self.value = Some(Dynamic(value.clone()));
//
// E::value(Flow::Done.into()).cast()
// }
// }
//
// impl<'ctx, T: 'static, E: Environment> Value<'ctx, BorrowedMutStatic<'ctx, T>, E>
// for ValueBuilder<T, Cloneable, E>
// where
// T: Clone,
// Dynamic<T>: DynBind<E>,
// Dynamic<BorrowedMutStatic<'ctx, T>>: DynBind<E>,
// {
// fn visit<'a>(
// &'a mut self,
// BorrowedMutStatic(value): BorrowedMutStatic<'ctx, T>,
// ) -> Canonical<'a, VisitResult<Dynamic<BorrowedMutStatic<'ctx, T>>>, E>
// where
// 'ctx: 'a,
// {
// self.value = Some(Dynamic(value.clone()));
//
// E::value(Flow::Done.into()).cast()
// }
// }
//
// impl<'ctx, T: 'static, E: Environment>
// Value<'ctx, type_name::Raised<'static, 'ctx, BorrowedMutStatic<'static, T>>, E>
// for ValueBuilder<T, Cloneable, E>
// where
// T: Clone,
// Dynamic<T>: DynBind<E>,
// for<'a> Dynamic<TempBorrowedMutStatic<'a, T>>: DynBind<E>,
// {
// fn visit<'a>(
// &'a mut self,
// TempBorrowedMutStatic(value): TempBorrowedMutStatic<'a, T>,
// ) -> Canonical<'a, VisitResult<Dynamic<TempBorrowedMutStatic<'a, T>>>, E>
// where
// 'ctx: 'a,
// {
// self.value = Some(Dynamic(value.clone()));
//
// E::value(Flow::Done.into()).cast()
// }
// }