radn-rs/src/std/tracing/rendered.rs
2023-04-24 17:23:17 +00:00

164 lines
4.2 KiB
Rust

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<T> {
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 [`Pure::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<WithLengthAndWidth<RenderedAny>>,
},
}
/// 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<WithLengthAndWidth<RenderedLong>>),
}
/// 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<WithLengthAndWidth<RenderedWide>>),
}
/// Represents an arbitrary rendered trace.
pub enum RenderedAny {
/// See [`RenderedCommon`].
Common(RenderedCommon),
/// Trace can be broken down in width.
Wide(Vec<WithLengthAndWidth<RenderedLong>>),
/// Trace can be broken down in length.
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()),
}
}
}