trace render
This commit is contained in:
parent
7b0626b05f
commit
dd5f8ccaf4
@ -279,4 +279,19 @@ mod tests {
|
||||
assert_eq!(format!("{}", traced.t), "( ? -> ? -> ? )");
|
||||
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 traced;
|
||||
|
||||
@ -5,6 +7,7 @@ use crate::core::*;
|
||||
|
||||
use super::*;
|
||||
|
||||
pub use self::rendered::*;
|
||||
use self::trace::*;
|
||||
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};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -5,9 +7,9 @@ enum Trace {
|
||||
Pure,
|
||||
InvolvesOneResolution,
|
||||
Event(String),
|
||||
Wrapped { name: String, trace: TraceBox },
|
||||
Parallel(TraceBox, TraceBox),
|
||||
Sequential { first: TraceBox, second: TraceBox },
|
||||
Wrapped { name: String, trace: TraceBox },
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -59,6 +61,7 @@ impl Display for Trace {
|
||||
Trace::Pure => f.write_fmt(format_args!(".")),
|
||||
Trace::InvolvesOneResolution => f.write_fmt(format_args!("?")),
|
||||
Trace::Event(event) => f.write_fmt(format_args!("{}", event)),
|
||||
Trace::Wrapped { name, trace } => f.write_fmt(format_args!("{} @ {}", name, trace)),
|
||||
Trace::Parallel(a, b) => {
|
||||
f.write_fmt(format_args!("( {} | {} )", ParallelBox(a), ParallelBox(b)))
|
||||
}
|
||||
@ -67,7 +70,6 @@ impl Display for Trace {
|
||||
SequentialBox(first),
|
||||
SequentialBox(second)
|
||||
)),
|
||||
Trace::Wrapped { name, trace } => f.write_fmt(format_args!("{} @ {}", name, trace)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -109,9 +111,9 @@ impl Trace {
|
||||
Self::Pure => 0,
|
||||
Self::InvolvesOneResolution => 1,
|
||||
Self::Event(_) => 0,
|
||||
Self::Wrapped { trace, .. } => trace.length(),
|
||||
Self::Parallel(a, b) => max(a.length(), b.length()),
|
||||
Self::Sequential { first, second } => first.length() + second.length(),
|
||||
Self::Wrapped { trace, .. } => trace.length(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,9 +122,9 @@ impl Trace {
|
||||
Self::Pure => 0,
|
||||
Self::InvolvesOneResolution => 1,
|
||||
Self::Event(_) => 0,
|
||||
Self::Wrapped { trace, .. } => trace.width(),
|
||||
Self::Parallel(a, b) => a.width() + b.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