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>, ignore_missing: bool, _marker: PhantomData (&'ctx (), E)>, } #[derive(Default)] pub enum IgnoreMissing { #[default] Yes, No, } #[derive(Debug)] pub enum Error { 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; type Value = Option; #[inline] fn build<'a>(self) -> Result 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>, >::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!(); } }