Diffstat (limited to 'src/build/builders/core/tracer.rs')
| -rw-r--r-- | src/build/builders/core/tracer.rs | 198 |
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 + } + } +} |