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 { 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>, }, } /// 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>), } /// 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>), } /// Represents an arbitrary rendered trace. pub enum RenderedAny { /// See [`RenderedCommon`]. Common(RenderedCommon), /// Trace can be broken down in width. Wide(Vec>), /// Trace can be broken down in length. Long(Vec>), } impl WithLengthAndWidth { pub fn push_into(self, vec: &mut WithLengthAndWidth>>) { vec.length += self.length; vec.width = max(vec.width, self.width); vec.value.push(self); } } impl WithLengthAndWidth { pub fn push_into(self, vec: &mut WithLengthAndWidth>>) { vec.width += self.width; vec.length = max(vec.length, self.length); vec.value.push(self); } } impl WithLengthAndWidth { pub fn map(self, f: impl FnOnce(A) -> B) -> WithLengthAndWidth { 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 Default for WithLengthAndWidth { fn default() -> Self { Self { length: 0, width: 0, value: Default::default(), } } } impl WithLengthAndWidth { pub fn wrap(self, name: &str) -> WithLengthAndWidth { WithLengthAndWidth { length: self.length, width: self.width, value: RenderedCommon::Action { name: name.into(), rendered: self.into(), }, } } } impl RenderedCommon { pub fn empty() -> WithLengthAndWidth { WithLengthAndWidth { length: 0, width: 0, value: RenderedCommon::Empty, } } pub fn resolution() -> WithLengthAndWidth { WithLengthAndWidth { length: 1, width: 1, value: RenderedCommon::Resolution, } } pub fn event(event: &str) -> WithLengthAndWidth { WithLengthAndWidth { length: 0, width: 0, value: RenderedCommon::Event(event.into()), } } }