use crate::BenchRounds;
use core::time::Duration;
pub type BenchRoutine<'routine> = Box<dyn FnMut(BenchRounds) -> Duration + 'routine>;
pub type BenchSentRoutine = Box<dyn FnMut(BenchRounds) -> Duration + Send>;
pub enum BenchCases<'routine> {
OneAtATime(Vec<(&'static str, BenchRoutine<'routine>)>),
Together(Vec<(&'static str, BenchSentRoutine)>),
}
impl BenchCases<'_> {
pub fn len(&self) -> usize {
match self {
Self::OneAtATime(cases) => cases.len(),
Self::Together(cases) => cases.len(),
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn subjects(&self) -> impl Iterator<Item = &'static str> + '_ {
match self {
Self::OneAtATime(cases) => Subjects::OneAtATime(cases.iter()),
Self::Together(cases) => Subjects::Together(cases.iter()),
}
}
}
enum Subjects<'cases, 'routine> {
OneAtATime(core::slice::Iter<'cases, (&'static str, BenchRoutine<'routine>)>),
Together(core::slice::Iter<'cases, (&'static str, BenchSentRoutine)>),
}
impl Iterator for Subjects<'_, '_> {
type Item = &'static str;
fn next(&mut self) -> Option<Self::Item> {
match self {
Self::OneAtATime(cases) => cases.next().map(|(subject, _)| *subject),
Self::Together(cases) => cases.next().map(|(subject, _)| *subject),
}
}
}
pub struct BenchGroup<'routine> {
group: &'static str,
cases: BenchCases<'routine>,
}
impl<'routine> BenchGroup<'routine> {
pub const fn new(group: &'static str, cases: BenchCases<'routine>) -> Self {
Self { group, cases }
}
pub const fn group(&self) -> &'static str {
self.group
}
pub fn cases(self) -> BenchCases<'routine> {
self.cases
}
pub const fn stated(&self) -> &BenchCases<'routine> {
&self.cases
}
}
#[derive(Default)]
pub struct BenchStated<'routine> {
groups: Vec<BenchGroup<'routine>>,
}
impl<'routine> BenchStated<'routine> {
pub const fn new() -> Self {
Self { groups: Vec::new() }
}
#[must_use]
pub fn group(mut self, group: BenchGroup<'routine>) -> Self {
self.groups.push(group);
self
}
#[must_use]
pub fn then(mut self, next: Self) -> Self {
self.groups.extend(next.groups);
self
}
pub fn groups(&self) -> impl Iterator<Item = &BenchGroup<'routine>> {
self.groups.iter()
}
pub fn into_groups(self) -> impl Iterator<Item = BenchGroup<'routine>> {
self.groups.into_iter()
}
}