From d9942857bc6536e86d537d2d33502a16d9557e7b Mon Sep 17 00:00:00 2001 From: timofey Date: Sun, 23 Apr 2023 22:01:43 +0000 Subject: [PATCH] extract traceable --- src/std/collections/stack.rs | 11 +++++---- src/std/tracing.rs | 9 +++++++ src/std/tracing/rendered.rs | 43 +++++++++++++++++++++++++++++++++ src/std/tracing/traceable.rs | 47 ++++++++++++++++++++++++++++++++++++ src/std/tracing/traced.rs | 5 +++- src/testing/traced.rs | 39 ------------------------------ 6 files changed, 109 insertions(+), 45 deletions(-) create mode 100644 src/std/tracing/traceable.rs diff --git a/src/std/collections/stack.rs b/src/std/collections/stack.rs index 6b6f191..a7a3650 100644 --- a/src/std/collections/stack.rs +++ b/src/std/collections/stack.rs @@ -205,12 +205,13 @@ where mod tests { use std::rc::Rc; + use crate::std::{ + atomic::{atomic_object::*, plain::*}, + tracing::*, + }; + use crate::testing::{counted::*, traced::*, *}; + use super::*; - use crate::std::atomic::atomic_object::*; - use crate::std::atomic::plain::*; - use crate::testing::counted::*; - use crate::testing::traced::*; - use crate::testing::*; type T = Stack<'static, Ctx, AtomicObject>; diff --git a/src/std/tracing.rs b/src/std/tracing.rs index facc3bd..771caf2 100644 --- a/src/std/tracing.rs +++ b/src/std/tracing.rs @@ -1,6 +1,9 @@ +//! Structures for tracing the execution flow of [Monad]s. + mod rendered; mod rendered_display; mod trace; +mod traceable; mod traced; use crate::core::*; @@ -9,10 +12,16 @@ use super::*; pub use self::rendered::*; use self::trace::*; +pub use self::traceable::*; pub use self::traced::*; +/// [`Diagnostic`] for [Traced] objects. +/// +/// [`Diagnostic::after`]/[`Diagnostic::before`] are represented in [`RenderedCommon::Event`]. +/// [`Diagnostic::wrapped`] is represented in [`RenderedCommon::Action`]. pub struct TracedDiagnostic; +/// Implementation of [`Monad`] for [Traced] objects. pub struct TracedClass; trait WithTrace: Sized { diff --git a/src/std/tracing/rendered.rs b/src/std/tracing/rendered.rs index 5c58c5f..1deb7ed 100644 --- a/src/std/tracing/rendered.rs +++ b/src/std/tracing/rendered.rs @@ -1,34 +1,77 @@ use std::cmp::max; +#[cfg(doc)] +use crate::core::*; +#[cfg(doc)] +use crate::func::*; + +#[cfg(doc)] +use super::*; + +/// Represents width (concurrency/throughput) and length (time/latency). +/// Use [`WithLengthAndWidth::length`] and [`WithLengthAndWidth::width`] to access them. pub struct WithLengthAndWidth { length: usize, width: usize, value: T, } +/// Rendered trace that can be broken down neither in width nor in length. pub enum RenderedCommon { + /// No resolutions are involved in getting the value. + /// + /// Usually, a result of [`Applicative::pure`]. + /// + /// Represented as 0x0 by default. + /// + /// Normally, is either at the root of the trace or wrapped into [`RenderedCommon::Action`]. Empty, + /// Exactly one resolution is involved in getting the value. + /// + /// Usually, a result of [`Traceable::trace`]. + /// + /// Represented as 1x1 by default. Resolution, + /// Arbitrary event for [Diagnostic]s. + /// + /// Usually, a result of [`Diagnostic::after`]/[`Diagnostic::before`]. + /// + /// Represented as 0x0 by default. Event(String), + /// Named action for [Diagnostic]s. + /// + /// Usually, a result of [`Diagnostic::wrapped`]. + /// + /// Represented with the same dimensions as the wrapped trace by default. Action { name: String, rendered: Box>, }, } +/// Rendered trace that cannot be broken down in length. pub enum RenderedWide { + /// See [`RenderedCommon`]. Common(RenderedCommon), + /// Trace can be broken down in width. Wide(Vec>), } +/// Rendered trace that cannot be broken down in width. pub enum RenderedLong { + /// See [`RenderedCommon`]. Common(RenderedCommon), + /// Trace can be broken down in length. Long(Vec>), } +/// Represents an arbitrary rendered trace. pub enum RenderedAny { + /// See [`RenderedCommon`]. Common(RenderedCommon), + /// Trace can be broken down in width. Wide(Vec>), + /// Trace can be broken down in length. Long(Vec>), } diff --git a/src/std/tracing/traceable.rs b/src/std/tracing/traceable.rs new file mode 100644 index 0000000..50909d7 --- /dev/null +++ b/src/std/tracing/traceable.rs @@ -0,0 +1,47 @@ +use crate::std::cast::*; + +use super::*; + +struct TracedResolver<'a, Ctx: 'a + Context> { + resolver: Rc>, +} + +impl<'a, Ctx: 'a + Context> TracedResolver<'a, Ctx> { + fn wrap(resolver: Rc>) -> Rc> { + Rc::new(Self { resolver }) + } +} + +impl<'a, Ctx: 'a + Context> Resolver<'a, Ctx> for TracedResolver<'a, Ctx> { + fn resolve(self: Rc, address: Address) -> HashResolution<'a, Ctx> { + TracedClass::fmap( + |resolved| { + let (src, resolver) = resolved?; + let delayed: Rc> = Rc::new(TracedResolver { resolver }); + Ok((src, delayed)) + }, + self.resolver.clone().resolve(address), + ) + .after_resolution() + } +} + +/// Extension trait to trace the evaluation flow. +pub trait Traceable<'a, Ctx: 'a + Context>: Mentionable<'a, Ctx> + Sized { + /// Re-cast the value, adding an extra[^extra] + /// note ([`RenderedCommon::Resolution`]) to the trace on each resolution. + /// + /// [^extra]: applying [`Traceable::trace`] multiple times + /// might affect the trace in undesireable ways + fn trace(self: Rc) -> CastResult<'a, Ctx, Self>; +} + +impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Traceable<'a, Ctx> for A +where + Ctx::LookupError<'a>: From>, +{ + fn trace(self: Rc) -> CastResult<'a, Ctx, Self> { + let factory = self.factory(); + TypelessMentionable::from_typed(self).cast_full(factory, TracedResolver::wrap) + } +} diff --git a/src/std/tracing/traced.rs b/src/std/tracing/traced.rs index 0df3391..ecb4b5d 100644 --- a/src/std/tracing/traced.rs +++ b/src/std/tracing/traced.rs @@ -1,5 +1,8 @@ -use super::trace::*; +use super::*; +/// Wrapper containing the value and the corresponding execution trace. +/// +/// For what the trace contains, see its rendered form, [`RenderedAny`]. pub struct Traced { pub a: A, pub t: TraceBox, diff --git a/src/testing/traced.rs b/src/testing/traced.rs index e14fe0b..34cfe95 100644 --- a/src/testing/traced.rs +++ b/src/testing/traced.rs @@ -1,5 +1,4 @@ use crate::core::*; -use crate::func::*; use crate::std::tracing::*; use super::*; @@ -17,41 +16,3 @@ impl Context for TestContextTraced { TestContextPlain::hash(s) } } - -struct TracedResolver<'a> { - resolver: Rc>, -} - -impl<'a> TracedResolver<'a> { - fn new( - resolver: Rc>, - ) -> Rc> { - Rc::new(Self { resolver }) - } -} - -impl<'a> Resolver<'a, TestContextTraced> for TracedResolver<'a> { - fn resolve(self: Rc, address: Address) -> HashResolution<'a, TestContextTraced> { - TracedClass::fmap( - |resolved| { - let (src, resolver) = resolved?; - let delayed: Rc> = - Rc::new(TracedResolver { resolver }); - Ok((src, delayed)) - }, - self.resolver.clone().resolve(address), - ) - .after_resolution() - } -} - -pub trait Traceable<'a>: Mentionable<'a, TestContextTraced> + Sized { - fn trace(self: Rc) -> CastResult<'a, TestContextTraced, Self>; -} - -impl<'a, A: Mentionable<'a, TestContextTraced>> Traceable<'a> for A { - fn trace(self: Rc) -> CastResult<'a, TestContextTraced, Self> { - let factory = self.factory(); - TypelessMentionable::from_typed(self).cast_full(factory, TracedResolver::new) - } -}