Diffstat (limited to 'src/build/builders/core/array.rs')
| -rw-r--r-- | src/build/builders/core/array.rs | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/src/build/builders/core/array.rs b/src/build/builders/core/array.rs index 8638fae..0c07561 100644 --- a/src/build/builders/core/array.rs +++ b/src/build/builders/core/array.rs @@ -1,12 +1,12 @@ -use core::{mem::MaybeUninit, ops::ControlFlow}; +use core::{marker::PhantomData, mem::MaybeUninit, ops::ControlFlow}; use crate::{ any_trait, protocol::{ visitor::{Sequence, SequenceScope, Status}, - ControlFlowFor, Effect, + AnyTraitObj, AnyTraitSendObj as _, ControlFlowFor, Effect, SyncEffect, }, - DefaultBuilder, + AsVisitor, DefaultBuilder, }; #[cfg(feature = "alloc")] @@ -15,12 +15,13 @@ use crate::protocol::AsyncEffect; #[cfg(all(feature = "alloc", not(feature = "std")))] use alloc::boxed::Box; -impl<'ctx, T, const N: usize> crate::Build<'ctx> for [T; N] +impl<'ctx, T, const N: usize, E: for<'a> Effect<'a, 'ctx>> crate::Build<'ctx, E> for [T; N] where - T: crate::Build<'ctx>, - <T as crate::Build<'ctx>>::Builder: DefaultBuilder<'ctx>, + T: crate::Build<'ctx, E>, + <T as crate::Build<'ctx, E>>::Builder: DefaultBuilder<'ctx, E>, + Builder<'ctx, T::Builder, N, E>: AsVisitor<'ctx, E>, { - type Builder = Builder<'ctx, T::Builder, N>; + type Builder = Builder<'ctx, T::Builder, N, E>; } #[derive(Debug)] @@ -29,23 +30,22 @@ pub enum ArrayError<E> { Item(usize, E), } -pub struct Builder<'ctx, B: crate::Builder<'ctx>, const N: usize> { +pub struct Builder<'ctx, B: crate::Builder<'ctx, E>, const N: usize, E: for<'a> Effect<'a, 'ctx>> { array: MaybeUninit<[B::Value; N]>, index: usize, item_err: Option<(usize, B::Error)>, + _marker: PhantomData<fn() -> E>, } -impl<'ctx, B: crate::DefaultBuilder<'ctx>, const N: usize> crate::Builder<'ctx> - for Builder<'ctx, B, N> +impl<'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: for<'a> Effect<'a, 'ctx>> crate::Builder<'ctx, E> + for Builder<'ctx, B, N, E> +where + Self: AsVisitor<'ctx, E>, { type Error = ArrayError<B::Error>; type Value = [B::Value; N]; - fn as_visitor(&mut self) -> &mut crate::protocol::Visitor<'_, 'ctx> { - self - } - fn build(self) -> Result<Self::Value, Self::Error> { if let Some((index, err)) = self.item_err { return Err(ArrayError::Item(index, err)); @@ -65,14 +65,23 @@ impl<'ctx, B: crate::DefaultBuilder<'ctx>, const N: usize> crate::Builder<'ctx> array: MaybeUninit::uninit(), index: 0, item_err: None, + _marker: PhantomData, } } } +impl<'ctx, B: crate::DefaultBuilder<'ctx, SyncEffect>, const N: usize> AsVisitor<'ctx, SyncEffect> + for Builder<'ctx, B, N, SyncEffect> +{ + fn as_visitor(&mut self) -> crate::protocol::Visitor<'_, 'ctx, SyncEffect> { + AnyTraitObj::from_obj(self) + } +} + // #[cfg(not(feature = "alloc"))] any_trait! { - impl['a, 'ctx, B: crate::DefaultBuilder<'ctx>, const N: usize] Builder<'ctx, B, N> = [ - dyn Sequence<'ctx> + 'a, + impl['a, 'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'a, 'ctx>] Builder<'ctx, B, N, E> = [ + dyn Sequence<'a, 'ctx> + 'a, ] } @@ -84,9 +93,11 @@ any_trait! { // ] // } -impl<'ctx, B: crate::DefaultBuilder<'ctx>, const N: usize> Sequence<'ctx> for Builder<'ctx, B, N> { +impl<'a, 'ctx, B: crate::DefaultBuilder<'ctx, E>, const N: usize, E: Effect<'a, 'ctx>> Sequence<'a, 'ctx> + for Builder<'ctx, B, N, E> +{ #[inline] - fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a> { + fn visit(&'a mut self, scope: &'a mut dyn for<'b> SequenceScope<'b, 'ctx>) -> ControlFlowFor<'a, 'ctx> { loop { // Check if the array is full. if self.index >= N { @@ -95,7 +106,7 @@ impl<'ctx, B: crate::DefaultBuilder<'ctx>, const N: usize> Sequence<'ctx> for Bu // Try to build the next value. let mut builder = B::default(); - match scope.next(builder.as_visitor()) { + match scope.next(builder.as_visitor().into_obj()) { ControlFlow::Continue(Status::Done) => { // The sequence is done so the builder wasn't given a value. // We just throw away the empty builder. |