180 lines
4.5 KiB
Rust
180 lines
4.5 KiB
Rust
use std::{cmp::max, fmt::Display};
|
|
|
|
pub mod render;
|
|
|
|
#[derive(Debug)]
|
|
enum Trace {
|
|
Pure,
|
|
InvolvesOneResolution,
|
|
Event(String),
|
|
Wrapped { name: String, trace: TraceBox },
|
|
Parallel(TraceBox, TraceBox),
|
|
Sequential { first: TraceBox, second: TraceBox },
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct TraceBox {
|
|
trace: Box<Trace>,
|
|
}
|
|
|
|
impl Trace {
|
|
fn fmt_parallel(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Parallel(a, b) => {
|
|
write!(f, "{} | {}", ParallelBox(a), ParallelBox(b))
|
|
}
|
|
trace => write!(f, "{}", trace),
|
|
}
|
|
}
|
|
|
|
fn fmt_sequential(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Sequential { first, second } => {
|
|
write!(f, "{} > {}", SequentialBox(first), SequentialBox(second))
|
|
}
|
|
trace => write!(f, "{}", trace),
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ParallelBox<'a>(&'a TraceBox);
|
|
|
|
struct SequentialBox<'a>(&'a TraceBox);
|
|
|
|
impl<'a> Display for ParallelBox<'a> {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
self.0.trace.fmt_parallel(f)
|
|
}
|
|
}
|
|
|
|
impl<'a> Display for SequentialBox<'a> {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
self.0.trace.fmt_sequential(f)
|
|
}
|
|
}
|
|
|
|
impl Display for Trace {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::Pure => write!(f, "."),
|
|
Self::InvolvesOneResolution => write!(f, "?"),
|
|
Self::Event(event) => write!(f, "{}", event),
|
|
Self::Wrapped { name, trace } => write!(f, "{} @ {}", name, trace),
|
|
Self::Parallel(a, b) => {
|
|
write!(f, "( {} | {} )", ParallelBox(a), ParallelBox(b))
|
|
}
|
|
Self::Sequential { first, second } => write!(
|
|
f,
|
|
"( {} > {} )",
|
|
SequentialBox(first),
|
|
SequentialBox(second)
|
|
),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for TraceBox {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.trace)
|
|
}
|
|
}
|
|
|
|
impl From<Trace> for TraceBox {
|
|
fn from(value: Trace) -> Self {
|
|
TraceBox {
|
|
trace: value.into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<TraceBox> for Trace {
|
|
fn from(value: TraceBox) -> Self {
|
|
*value.trace
|
|
}
|
|
}
|
|
|
|
impl Trace {
|
|
fn sequential(ta: Self, tb: Self) -> Self {
|
|
match (ta, tb) {
|
|
(Trace::Pure, a) => a,
|
|
(a, Trace::Pure) => a,
|
|
(a, b) => Trace::Sequential {
|
|
first: a.into(),
|
|
second: b.into(),
|
|
},
|
|
}
|
|
}
|
|
|
|
fn length(&self) -> usize {
|
|
match self {
|
|
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(),
|
|
}
|
|
}
|
|
|
|
fn width(&self) -> usize {
|
|
match self {
|
|
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()),
|
|
}
|
|
}
|
|
|
|
fn parallel(ta: Self, tb: Self) -> Self {
|
|
match (ta, tb) {
|
|
(Trace::Pure, a) => a,
|
|
(a, Trace::Pure) => a,
|
|
(a, b) => Trace::Parallel(a.into(), b.into()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TraceBox {
|
|
pub fn pure() -> Self {
|
|
Trace::Pure.into()
|
|
}
|
|
|
|
pub fn resolution() -> Self {
|
|
Trace::InvolvesOneResolution.into()
|
|
}
|
|
|
|
pub fn event(event: String) -> Self {
|
|
Trace::Event(event).into()
|
|
}
|
|
|
|
pub fn wrapped(self, event: String) -> Self {
|
|
Trace::Wrapped {
|
|
name: event,
|
|
trace: self,
|
|
}
|
|
.into()
|
|
}
|
|
|
|
pub fn after(self, t: Self) -> Self {
|
|
Trace::sequential(t.into(), self.into()).into()
|
|
}
|
|
|
|
pub fn before(self, t: Self) -> Self {
|
|
Trace::sequential(self.into(), t.into()).into()
|
|
}
|
|
|
|
pub fn parallel(ta: Self, tb: Self) -> Self {
|
|
Trace::parallel(ta.into(), tb.into()).into()
|
|
}
|
|
|
|
pub fn length(&self) -> usize {
|
|
self.trace.length()
|
|
}
|
|
|
|
pub fn width(&self) -> usize {
|
|
self.trace.width()
|
|
}
|
|
}
|