Diffstat (limited to 'src/build/builders/core/tracer.rs')
-rw-r--r--src/build/builders/core/tracer.rs198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/build/builders/core/tracer.rs b/src/build/builders/core/tracer.rs
new file mode 100644
index 0000000..c4d5b5c
--- /dev/null
+++ b/src/build/builders/core/tracer.rs
@@ -0,0 +1,198 @@
+use core::any::type_name;
+
+use crate::any::type_name::{Lowered, Raised};
+use crate::any::{BorrowedStatic, MutAnyUnsized, OwnedStatic};
+use crate::protocol::DynWalker;
+use effectful::effective::Canonical;
+use effectful::{DynBind, Effective, Environment, SendSync};
+
+use crate::protocol::visitor::{request_hint, visit_value, RequestHint, Value, VisitResult};
+use crate::trait_by_id;
+use crate::{
+ any::AnyTrait,
+ build::BuilderTypes,
+ hkt::Marker,
+ protocol::{AsVisitor, DynVisitor},
+ Builder,
+};
+
+#[derive(SendSync)]
+pub struct Tracer<B, E> {
+ inner: B,
+ _env: Marker<E>,
+}
+
+impl<B, E: Environment> BuilderTypes<E> for Tracer<B, E>
+where
+ B: BuilderTypes<E>,
+{
+ type Seed = B::Seed;
+
+ type Error = B::Error;
+
+ type Output = B::Output;
+
+ type Value = B::Value;
+
+ fn unwrap_output(output: Self::Output) -> Self::Value {
+ println!("Unwrapped output value");
+ B::unwrap_output(output)
+ }
+}
+
+impl<'src, B, E: Environment> Builder<'src, E> for Tracer<B, E>
+where
+ B: Builder<'src, E>,
+{
+ fn from_seed<'u>(seed: Self::Seed) -> effectful::effective::Canonical<'u, Self, E>
+ where
+ Self: 'u,
+ {
+ println!("Created builder from seed value: {}", type_name::<B>());
+ B::from_seed(seed)
+ .map((), |_, b| Self {
+ inner: b,
+ _env: Marker::NEW,
+ })
+ .cast()
+ }
+
+ fn build<'u>(self) -> effectful::effective::Canonical<'u, Result<Self::Output, Self::Error>, E>
+ where
+ Self: 'u,
+ {
+ println!("Built value");
+ self.inner.build()
+ }
+}
+
+impl<'src, B, E: Environment> AsVisitor<'src, E> for Tracer<B, E>
+where
+ Self: DynBind<E> + AnyTrait<'src>,
+{
+ fn as_visitor(&mut self) -> crate::protocol::DynVisitor<'_, 'src, E> {
+ println!("Converted builder to visitor");
+ DynVisitor::new(self)
+ }
+}
+
+impl<'src, B, E: Environment> AnyTrait<'src> for Tracer<B, E>
+where
+ B: AsVisitor<'src, E>,
+ Self: Value<'src, OwnedStatic<i32>, E>
+ + Value<'src, Raised<'src, 'src, BorrowedStatic<'src, i32>>, E>
+ + RequestHint<'src, E>,
+{
+ fn upcast_by_id_mut(
+ &mut self,
+ id: crate::any::WithLtTypeId<'src>,
+ ) -> Option<crate::any::MutAnyUnsized<'_, 'src>> {
+ if self
+ .inner
+ .as_visitor()
+ .upcast_by_id_mut(id)
+ .is_some()
+ {
+ trait_by_id!(&mut self, id, {
+ type Impls = (
+ dyn Value<'_, OwnedStatic<i32>, E>,
+ dyn Value<'_, Raised<'_, '_, BorrowedStatic<'_, i32>>, E>,
+ dyn RequestHint<'_, E>,
+ );
+ });
+
+ println!("Unknown protocol for Tracer: {:?}", id);
+ self.inner
+ .as_visitor()
+ .into_inner()
+ .as_any_trait_mut()
+ .upcast_by_id_mut(id)
+ } else {
+ println!("Unknown protocol for builder: {:?}", id);
+ None
+ }
+ }
+}
+
+impl<'src, B, E: Environment> Value<'src, OwnedStatic<i32>, E> for Tracer<B, E>
+where
+ B: AsVisitor<'src, E> + DynBind<E>,
+{
+ fn visit<'r>(
+ &'r mut self,
+ value: OwnedStatic<i32>,
+ ) -> Canonical<'r, VisitResult<OwnedStatic<i32>>, E>
+ where
+ 'src: 'r,
+ Lowered<'r, 'src, OwnedStatic<i32>>: Sized + DynBind<E>,
+ {
+ println!("Visited i32: {}", value.0);
+ visit_value(self.inner.as_visitor(), value)
+ }
+}
+
+impl<'src, B, E: Environment> Value<'src, Raised<'src, 'src, BorrowedStatic<'src, i32>>, E>
+ for Tracer<B, E>
+where
+ B: AsVisitor<'src, E> + DynBind<E>,
+{
+ fn visit<'r>(
+ &'r mut self,
+ value: BorrowedStatic<'src, i32>,
+ ) -> Canonical<'r, VisitResult<BorrowedStatic<'src, i32>>, E>
+ where
+ 'src: 'r,
+ Lowered<'r, 'src, OwnedStatic<i32>>: Sized + DynBind<E>,
+ {
+ println!("Visited 'src borrow of i32: {}", value.0);
+ visit_value(self.inner.as_visitor(), value)
+ }
+}
+
+impl<'src, B, E: Environment> RequestHint<'src, E>
+ for Tracer<B, E>
+where
+ B: AsVisitor<'src, E> + DynBind<E>,
+{
+ fn request_hint<'r>(
+ &'r mut self,
+ walker: DynWalker<'r, 'src, E>,
+ ) -> Canonical<'r, VisitResult, E> {
+ println!("Walker requested hint");
+ let walker = WalkerTracer::<E> { inner: walker };
+ E::value((self, walker)).update_map((), |_, (this, walker)| {
+ request_hint(this.inner.as_visitor(), DynWalker::new(walker)).map((), |_, x| x.unit_skipped()).cast()
+ }).map((), |_, (_, result)| result).cast()
+ }
+}
+
+#[derive(SendSync)]
+struct WalkerTracer<'r, 'src, E: Environment> {
+ inner: DynWalker<'r, 'src, E>,
+}
+
+impl<'r, 'src, E: Environment> AnyTrait<'src> for WalkerTracer<'r, 'src, E>
+{
+ fn upcast_by_id_mut(
+ &mut self,
+ id: crate::any::WithLtTypeId<'src>,
+ ) -> Option<crate::any::MutAnyUnsized<'_, 'src>> {
+ if self
+ .inner
+ .upcast_by_id_mut(id)
+ .is_some()
+ {
+ trait_by_id!(&mut self, id, {
+ type Impls = (
+ );
+ });
+
+ println!("Unknown walker protocol for Tracer: {:?}", id);
+ self.inner
+ .upcast_by_id_mut(id)
+ } else {
+ println!("Unknown protocol for walker: {:?}", id);
+ None
+ }
+ }
+}