trace render

This commit is contained in:
AF 2023-04-23 20:59:36 +00:00
parent 7b0626b05f
commit dd5f8ccaf4
6 changed files with 340 additions and 4 deletions

View File

@ -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(())
}
}

View File

@ -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
View 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()),
}
}
}

View 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))),
}
}
}

View File

@ -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(),
}
}

View 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),
}
}
}