Diffstat (limited to 'src/transform.rs')
-rw-r--r--src/transform.rs85
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)
+ })
+ }
+}