Diffstat (limited to 'src/transform.rs')
| -rw-r--r-- | src/transform.rs | 85 |
1 files changed, 84 insertions, 1 deletions
diff --git a/src/transform.rs b/src/transform.rs index 64aea20..edfa92a 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -1,7 +1,8 @@ use crate::{ build::Builder, effect::{Effect, Future}, - Walker, + hkt::Marker, + Walk, Walker, WalkerTypes, }; #[inline] @@ -23,3 +24,85 @@ pub fn transform<'a, 'ctx, B: Builder<'ctx, E> + 'a, W: Walker<'ctx, E> + 'a, E: (builder_result, walker_result) }) } + +/// For use in a lens. +pub struct Projection<T, B, U, M> { + value: T, + builder: B, + _marker: Marker<(U, M)>, +} + +impl<T, B, U: Send + Sync, M> Projection<T, B, U, M> { + pub fn project_ref<'a, E: Effect>( + &'a self, + ) -> Future< + 'a, + ( + Result<&'a U, B::Error>, + Result<<&'a T as WalkerTypes>::Output, <&'a T as WalkerTypes>::Error>, + ), + E, + > + where + &'a T: Walk<'a, M, E>, + B: Clone + Builder<'a, E, Value = &'a U>, + { + let walker = self.value.into_walker(); + let mut builder = self.builder.clone(); + + E::wrap(async { + let result = walker.walk(builder.as_visitor()).await; + + (builder.build().await, result) + }) + } + + pub fn project_mut<'a, E: Effect>( + &'a mut self, + ) -> Future< + 'a, + ( + Result<&'a mut U, B::Error>, + Result<<&'a mut T as WalkerTypes>::Output, <&'a mut T as WalkerTypes>::Error>, + ), + E, + > + where + &'a mut T: Walk<'a, M, E>, + B: Clone + Builder<'a, E, Value = &'a mut U>, + { + let walker = self.value.into_walker(); + let mut builder = self.builder.clone(); + + E::wrap(async { + let result = walker.walk(builder.as_visitor()).await; + + (builder.build().await, result) + }) + } + + pub fn project<'a, E: Effect>( + self, + ) -> Future< + 'a, + ( + Result<U, B::Error>, + Result<<T as WalkerTypes>::Output, <T as WalkerTypes>::Error>, + ), + E, + > + where + T: Walk<'a, M, E> + 'a, + M: 'a, + B: Clone + Builder<'a, E, Value = U> + 'a, + { + let walker = self.value.into_walker(); + let mut builder = self.builder.clone(); + + E::wrap(async { + let result = walker.walk(builder.as_visitor()).await; + + (builder.build().await, result) + }) + } +} |