trace render
This commit is contained in:
parent
7b0626b05f
commit
dd5f8ccaf4
@ -279,4 +279,19 @@ mod tests {
|
|||||||
assert_eq!(format!("{}", traced.t), "( ? -> ? -> ? )");
|
assert_eq!(format!("{}", traced.t), "( ? -> ? -> ? )");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rendered() -> Result<(), point::PointParseError> {
|
||||||
|
let stack: T<TestContextTraced> = make_stack();
|
||||||
|
let rendered = stack.clone().vec().render();
|
||||||
|
assert_eq!(rendered.length(), 0);
|
||||||
|
assert_eq!(rendered.width(), 0);
|
||||||
|
assert_eq!(format!("{}", rendered), ".");
|
||||||
|
let stack: T<TestContextTraced> = Rc::new(stack).trace()?;
|
||||||
|
let rendered = stack.clone().vec().render();
|
||||||
|
assert_eq!(rendered.length(), 3);
|
||||||
|
assert_eq!(rendered.width(), 1);
|
||||||
|
assert_eq!(format!("{}", rendered), "( ? -> ? -> ? )");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
mod rendered;
|
||||||
|
mod rendered_display;
|
||||||
mod trace;
|
mod trace;
|
||||||
mod traced;
|
mod traced;
|
||||||
|
|
||||||
@ -5,6 +7,7 @@ use crate::core::*;
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
pub use self::rendered::*;
|
||||||
use self::trace::*;
|
use self::trace::*;
|
||||||
pub use self::traced::*;
|
pub use self::traced::*;
|
||||||
|
|
||||||
|
120
src/std/tracing/rendered.rs
Normal file
120
src/std/tracing/rendered.rs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
use std::cmp::max;
|
||||||
|
|
||||||
|
pub struct WithLengthAndWidth<T> {
|
||||||
|
length: usize,
|
||||||
|
width: usize,
|
||||||
|
value: T,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum RenderedCommon {
|
||||||
|
Empty,
|
||||||
|
Resolution,
|
||||||
|
Event(String),
|
||||||
|
Action {
|
||||||
|
name: String,
|
||||||
|
rendered: Box<WithLengthAndWidth<RenderedAny>>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum RenderedWide {
|
||||||
|
Common(RenderedCommon),
|
||||||
|
Wide(Vec<WithLengthAndWidth<RenderedLong>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum RenderedLong {
|
||||||
|
Common(RenderedCommon),
|
||||||
|
Long(Vec<WithLengthAndWidth<RenderedWide>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum RenderedAny {
|
||||||
|
Common(RenderedCommon),
|
||||||
|
Wide(Vec<WithLengthAndWidth<RenderedLong>>),
|
||||||
|
Long(Vec<WithLengthAndWidth<RenderedWide>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithLengthAndWidth<RenderedWide> {
|
||||||
|
pub fn push_into(self, vec: &mut WithLengthAndWidth<Vec<WithLengthAndWidth<RenderedWide>>>) {
|
||||||
|
vec.length += self.length;
|
||||||
|
vec.width = max(vec.width, self.width);
|
||||||
|
vec.value.push(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithLengthAndWidth<RenderedLong> {
|
||||||
|
pub fn push_into(self, vec: &mut WithLengthAndWidth<Vec<WithLengthAndWidth<RenderedLong>>>) {
|
||||||
|
vec.width += self.width;
|
||||||
|
vec.length = max(vec.length, self.length);
|
||||||
|
vec.value.push(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> WithLengthAndWidth<A> {
|
||||||
|
pub fn map<B>(self, f: impl FnOnce(A) -> B) -> WithLengthAndWidth<B> {
|
||||||
|
WithLengthAndWidth {
|
||||||
|
length: self.length,
|
||||||
|
width: self.width,
|
||||||
|
value: f(self.value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn length(&self) -> usize {
|
||||||
|
self.length
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn width(&self) -> usize {
|
||||||
|
self.width
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn value(&self) -> &A {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: Default> Default for WithLengthAndWidth<A> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
length: 0,
|
||||||
|
width: 0,
|
||||||
|
value: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithLengthAndWidth<RenderedAny> {
|
||||||
|
pub fn wrap(self, name: &str) -> WithLengthAndWidth<RenderedCommon> {
|
||||||
|
WithLengthAndWidth {
|
||||||
|
length: self.length,
|
||||||
|
width: self.width,
|
||||||
|
value: RenderedCommon::Action {
|
||||||
|
name: name.into(),
|
||||||
|
rendered: self.into(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderedCommon {
|
||||||
|
pub fn empty() -> WithLengthAndWidth<Self> {
|
||||||
|
WithLengthAndWidth {
|
||||||
|
length: 0,
|
||||||
|
width: 0,
|
||||||
|
value: RenderedCommon::Empty,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resolution() -> WithLengthAndWidth<Self> {
|
||||||
|
WithLengthAndWidth {
|
||||||
|
length: 1,
|
||||||
|
width: 1,
|
||||||
|
value: RenderedCommon::Resolution,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn event(event: &str) -> WithLengthAndWidth<Self> {
|
||||||
|
WithLengthAndWidth {
|
||||||
|
length: 0,
|
||||||
|
width: 0,
|
||||||
|
value: RenderedCommon::Event(event.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
78
src/std/tracing/rendered_display.rs
Normal file
78
src/std/tracing/rendered_display.rs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
impl<A: Display> Display for WithLengthAndWidth<A> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("{}", self.value()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for RenderedAny {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
RenderedAny::Common(common) => f.write_fmt(format_args!("{}", common)),
|
||||||
|
RenderedAny::Wide(vec) => f.write_fmt(format_args!("( {} )", RenderVec(vec))),
|
||||||
|
RenderedAny::Long(vec) => f.write_fmt(format_args!("( {} )", RenderVec(vec))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for RenderedCommon {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
RenderedCommon::Empty => f.write_fmt(format_args!(".")),
|
||||||
|
RenderedCommon::Resolution => f.write_fmt(format_args!("?")),
|
||||||
|
RenderedCommon::Event(event) => f.write_fmt(format_args!("{}", event)),
|
||||||
|
RenderedCommon::Action { name, rendered } => {
|
||||||
|
f.write_fmt(format_args!("{} @ {}", name, rendered))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RenderVec<T>(T);
|
||||||
|
|
||||||
|
impl Display for RenderVec<&Vec<WithLengthAndWidth<RenderedWide>>> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mut delimiter = "";
|
||||||
|
let mut tail = "~";
|
||||||
|
for rendered in self.0 {
|
||||||
|
f.write_fmt(format_args!("{}{}", delimiter, rendered))?;
|
||||||
|
delimiter = " -> ";
|
||||||
|
tail = "";
|
||||||
|
}
|
||||||
|
f.write_fmt(format_args!("{}", tail))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for RenderVec<&Vec<WithLengthAndWidth<RenderedLong>>> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mut delimiter = "";
|
||||||
|
let mut tail = "~";
|
||||||
|
for rendered in self.0 {
|
||||||
|
f.write_fmt(format_args!("{}{}", delimiter, rendered))?;
|
||||||
|
delimiter = " | ";
|
||||||
|
tail = "";
|
||||||
|
}
|
||||||
|
f.write_fmt(format_args!("{}", tail))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for RenderedLong {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
RenderedLong::Common(common) => f.write_fmt(format_args!("{}", common)),
|
||||||
|
RenderedLong::Long(vec) => f.write_fmt(format_args!("( {} )", RenderVec(vec))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for RenderedWide {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
RenderedWide::Common(common) => f.write_fmt(format_args!("{}", common)),
|
||||||
|
RenderedWide::Wide(vec) => f.write_fmt(format_args!("( {} )", RenderVec(vec))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
pub mod render;
|
||||||
|
|
||||||
use std::{cmp::max, fmt::Display};
|
use std::{cmp::max, fmt::Display};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -5,9 +7,9 @@ enum Trace {
|
|||||||
Pure,
|
Pure,
|
||||||
InvolvesOneResolution,
|
InvolvesOneResolution,
|
||||||
Event(String),
|
Event(String),
|
||||||
|
Wrapped { name: String, trace: TraceBox },
|
||||||
Parallel(TraceBox, TraceBox),
|
Parallel(TraceBox, TraceBox),
|
||||||
Sequential { first: TraceBox, second: TraceBox },
|
Sequential { first: TraceBox, second: TraceBox },
|
||||||
Wrapped { name: String, trace: TraceBox },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -59,6 +61,7 @@ impl Display for Trace {
|
|||||||
Trace::Pure => f.write_fmt(format_args!(".")),
|
Trace::Pure => f.write_fmt(format_args!(".")),
|
||||||
Trace::InvolvesOneResolution => f.write_fmt(format_args!("?")),
|
Trace::InvolvesOneResolution => f.write_fmt(format_args!("?")),
|
||||||
Trace::Event(event) => f.write_fmt(format_args!("{}", event)),
|
Trace::Event(event) => f.write_fmt(format_args!("{}", event)),
|
||||||
|
Trace::Wrapped { name, trace } => f.write_fmt(format_args!("{} @ {}", name, trace)),
|
||||||
Trace::Parallel(a, b) => {
|
Trace::Parallel(a, b) => {
|
||||||
f.write_fmt(format_args!("( {} | {} )", ParallelBox(a), ParallelBox(b)))
|
f.write_fmt(format_args!("( {} | {} )", ParallelBox(a), ParallelBox(b)))
|
||||||
}
|
}
|
||||||
@ -67,7 +70,6 @@ impl Display for Trace {
|
|||||||
SequentialBox(first),
|
SequentialBox(first),
|
||||||
SequentialBox(second)
|
SequentialBox(second)
|
||||||
)),
|
)),
|
||||||
Trace::Wrapped { name, trace } => f.write_fmt(format_args!("{} @ {}", name, trace)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,9 +111,9 @@ impl Trace {
|
|||||||
Self::Pure => 0,
|
Self::Pure => 0,
|
||||||
Self::InvolvesOneResolution => 1,
|
Self::InvolvesOneResolution => 1,
|
||||||
Self::Event(_) => 0,
|
Self::Event(_) => 0,
|
||||||
|
Self::Wrapped { trace, .. } => trace.length(),
|
||||||
Self::Parallel(a, b) => max(a.length(), b.length()),
|
Self::Parallel(a, b) => max(a.length(), b.length()),
|
||||||
Self::Sequential { first, second } => first.length() + second.length(),
|
Self::Sequential { first, second } => first.length() + second.length(),
|
||||||
Self::Wrapped { trace, .. } => trace.length(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,9 +122,9 @@ impl Trace {
|
|||||||
Self::Pure => 0,
|
Self::Pure => 0,
|
||||||
Self::InvolvesOneResolution => 1,
|
Self::InvolvesOneResolution => 1,
|
||||||
Self::Event(_) => 0,
|
Self::Event(_) => 0,
|
||||||
|
Self::Wrapped { trace, .. } => trace.width(),
|
||||||
Self::Parallel(a, b) => a.width() + b.width(),
|
Self::Parallel(a, b) => a.width() + b.width(),
|
||||||
Self::Sequential { first, second } => max(first.width(), second.width()),
|
Self::Sequential { first, second } => max(first.width(), second.width()),
|
||||||
Self::Wrapped { trace, .. } => trace.width(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
118
src/std/tracing/trace/render.rs
Normal file
118
src/std/tracing/trace/render.rs
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
use crate::std::tracing::{rendered::*, *};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
enum TraceCommon<'a> {
|
||||||
|
Pure,
|
||||||
|
InvolvesOneResolution,
|
||||||
|
Event(&'a str),
|
||||||
|
Wrapped { name: &'a str, trace: &'a Trace },
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TraceAny<'a> {
|
||||||
|
Common(TraceCommon<'a>),
|
||||||
|
Parallel(&'a Trace, &'a Trace),
|
||||||
|
Sequential { first: &'a Trace, second: &'a Trace },
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trace {
|
||||||
|
fn any(&self) -> TraceAny<'_> {
|
||||||
|
match self {
|
||||||
|
Trace::Pure => TraceAny::Common(TraceCommon::Pure),
|
||||||
|
Trace::InvolvesOneResolution => TraceAny::Common(TraceCommon::InvolvesOneResolution),
|
||||||
|
Trace::Event(event) => TraceAny::Common(TraceCommon::Event(event)),
|
||||||
|
Trace::Wrapped { name, trace } => TraceAny::Common(TraceCommon::Wrapped {
|
||||||
|
name,
|
||||||
|
trace: &trace.trace,
|
||||||
|
}),
|
||||||
|
Trace::Parallel(a, b) => TraceAny::Parallel(&a.trace, &b.trace),
|
||||||
|
Trace::Sequential { first, second } => TraceAny::Sequential {
|
||||||
|
first: &first.trace,
|
||||||
|
second: &second.trace,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render(&self) -> WithLengthAndWidth<RenderedAny> {
|
||||||
|
self.any().render()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A> Traced<A> {
|
||||||
|
pub fn render(&self) -> WithLengthAndWidth<RenderedAny> {
|
||||||
|
self.t.trace.render()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_sequential(
|
||||||
|
first: &Trace,
|
||||||
|
second: &Trace,
|
||||||
|
) -> WithLengthAndWidth<Vec<WithLengthAndWidth<RenderedWide>>> {
|
||||||
|
let mut vec = WithLengthAndWidth::default();
|
||||||
|
first.any().render_into_long(&mut vec);
|
||||||
|
second.any().render_into_long(&mut vec);
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_parallel(
|
||||||
|
a: &Trace,
|
||||||
|
b: &Trace,
|
||||||
|
) -> WithLengthAndWidth<Vec<WithLengthAndWidth<RenderedLong>>> {
|
||||||
|
let mut vec = WithLengthAndWidth::default();
|
||||||
|
a.any().render_into_wide(&mut vec);
|
||||||
|
b.any().render_into_wide(&mut vec);
|
||||||
|
vec
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TraceAny<'a> {
|
||||||
|
fn render(&'a self) -> WithLengthAndWidth<RenderedAny> {
|
||||||
|
match self {
|
||||||
|
TraceAny::Common(common) => common.render().map(RenderedAny::Common),
|
||||||
|
TraceAny::Parallel(a, b) => from_parallel(a, b).map(RenderedAny::Wide),
|
||||||
|
TraceAny::Sequential { first, second } => {
|
||||||
|
from_sequential(first, second).map(RenderedAny::Long)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_into_long(
|
||||||
|
&'a self,
|
||||||
|
vec: &mut WithLengthAndWidth<Vec<WithLengthAndWidth<RenderedWide>>>,
|
||||||
|
) {
|
||||||
|
match self {
|
||||||
|
TraceAny::Common(common) => common.render().map(RenderedWide::Common).push_into(vec),
|
||||||
|
TraceAny::Parallel(a, b) => from_parallel(a, b).map(RenderedWide::Wide).push_into(vec),
|
||||||
|
TraceAny::Sequential { first, second } => {
|
||||||
|
first.any().render_into_long(vec);
|
||||||
|
second.any().render_into_long(vec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_into_wide(
|
||||||
|
&'a self,
|
||||||
|
vec: &mut WithLengthAndWidth<Vec<WithLengthAndWidth<RenderedLong>>>,
|
||||||
|
) {
|
||||||
|
match self {
|
||||||
|
TraceAny::Common(common) => common.render().map(RenderedLong::Common).push_into(vec),
|
||||||
|
TraceAny::Parallel(a, b) => {
|
||||||
|
a.any().render_into_wide(vec);
|
||||||
|
b.any().render_into_wide(vec);
|
||||||
|
}
|
||||||
|
TraceAny::Sequential { first, second } => from_sequential(first, second)
|
||||||
|
.map(RenderedLong::Long)
|
||||||
|
.push_into(vec),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TraceCommon<'a> {
|
||||||
|
fn render(&'a self) -> WithLengthAndWidth<RenderedCommon> {
|
||||||
|
match self {
|
||||||
|
TraceCommon::Pure => RenderedCommon::empty(),
|
||||||
|
TraceCommon::InvolvesOneResolution => RenderedCommon::resolution(),
|
||||||
|
TraceCommon::Event(event) => RenderedCommon::event(event),
|
||||||
|
TraceCommon::Wrapped { name, trace } => trace.any().render().wrap(name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user