use core::{marker::PhantomData, ops::ControlFlow};
use crate::{
any::static_wrapper::OwnedStatic,
any_trait,
effect::{AsyncEffect, AsyncSendEffect, EffectAnyTrait, SyncEffect, Yield},
protocol::visitor::{Tagged, TaggedScope, Value},
AsVisitor,
};
pub struct VariantInfo<'ctx> {
pub
}
pub struct Builder<'ctx, E: EffectAnyTrait<'ctx>> {
value: Option<Option<B::Value>>,
ignore_missing: bool,
_marker: PhantomData<fn() -> (&'ctx (), E)>,
}
#[derive(Default)]
pub enum IgnoreMissing {
#[default]
Yes,
No,
}
#[derive(Debug)]
pub enum Error<T> {
Missing,
VariantNone,
VariantSome(T),
}
impl<'ctx, B, E> crate::Builder<'ctx, E> for Builder<'ctx, B, E>
where
E: EffectAnyTrait<'ctx>,
Self: AsVisitor<'ctx, E>,
B: crate::Builder<'ctx, E>,
{
type Error = Error<B::Error>;
type Value = Option<B::Value>;
#[inline]
fn build<'a>(self) -> Result<Self::Value, Self::Error>
where
Self: 'a,
{
if self.ignore_missing {
Ok(self.value.flatten())
} else {
self.value.ok_or(Error::Missing)
}
}
type Seed = IgnoreMissing;
fn from_seed(seed: Self::Seed) -> Self {
Self {
value: None,
ignore_missing: match seed {
IgnoreMissing::Yes => true,
IgnoreMissing::No => false,
},
_marker: PhantomData,
}
}
type Effect = SyncEffect;
}
impl<'ctx, B: crate::Builder<'ctx, SyncEffect>> AsVisitor<'ctx, SyncEffect>
for Builder<'ctx, B, SyncEffect>
{
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> {
self
}
}
impl<'ctx, B: crate::Builder<'ctx, AsyncEffect>> AsVisitor<'ctx, AsyncEffect>
for Builder<'ctx, B, AsyncEffect>
{
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncEffect> {
self
}
}
impl<'ctx, B> AsVisitor<'ctx, AsyncSendEffect> for Builder<'ctx, B, AsyncSendEffect>
where
B: crate::Builder<'ctx, AsyncSendEffect>,
<B as crate::Builder<'ctx, AsyncSendEffect>>::Value: Send,
{
fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, AsyncSendEffect> {
self
}
}
any_trait! {
impl['a, 'ctx, B] Builder<'ctx, B, SyncEffect> = [
] where B: crate::Builder<'ctx, SyncEffect>
}
any_trait! {
impl['a, 'ctx, B] Builder<'ctx, B, AsyncEffect> = [
] where B: crate::Builder<'ctx, AsyncEffect>
}
any_trait! {
impl['a, 'ctx, B] Builder<'ctx, B, AsyncSendEffect> = [
] where B: crate::Builder<'ctx, AsyncSendEffect>
}
pub mod symbol {
use crate::symbol::Symbol;
pub const TYPE: Symbol = Symbol::new("Type");
pub const VARIANT: Symbol = Symbol::new("Variant");
}
impl<'ctx, B> Tagged<'ctx, SyncEffect> for Builder<'ctx, B, SyncEffect>
where
B: crate::Builder<'ctx, SyncEffect>,
{
fn visit<'a>(
&'a mut self,
scope: &'a mut dyn TaggedScope<'ctx, SyncEffect>,
) -> Yield<'a, 'ctx, ControlFlow<(), ()>, SyncEffect>
where
'ctx: 'a,
{
match scope.kind() {
symbol::TYPE => {
// The type info doesn't matter, just move on to the value.
scope.value(self)?;
},
symbol::VARIANT => {
// We need to check the variant id.
// let mut variant = VariantBuilder::from_seed(());
},
_ => {}
}
todo!();
}
}