1use crate::BenchRounds;
8use core::time::Duration;
9
10pub type BenchRoutine<'routine> = Box<dyn FnMut(BenchRounds) -> Duration + 'routine>;
12
13pub type BenchSentRoutine = Box<dyn FnMut(BenchRounds) -> Duration + Send>;
15
16pub enum BenchCases<'routine> {
18 OneAtATime(Vec<(&'static str, BenchRoutine<'routine>)>),
21 Together(Vec<(&'static str, BenchSentRoutine)>),
24}
25
26impl BenchCases<'_> {
27 pub fn len(&self) -> usize {
29 match self {
30 Self::OneAtATime(cases) => cases.len(),
31 Self::Together(cases) => cases.len(),
32 }
33 }
34
35 pub fn is_empty(&self) -> bool {
37 self.len() == 0
38 }
39
40 pub fn subjects(&self) -> impl Iterator<Item = &'static str> + '_ {
42 match self {
43 Self::OneAtATime(cases) => Subjects::OneAtATime(cases.iter()),
44 Self::Together(cases) => Subjects::Together(cases.iter()),
45 }
46 }
47}
48
49enum Subjects<'cases, 'routine> {
51 OneAtATime(core::slice::Iter<'cases, (&'static str, BenchRoutine<'routine>)>),
52 Together(core::slice::Iter<'cases, (&'static str, BenchSentRoutine)>),
53}
54
55impl Iterator for Subjects<'_, '_> {
56 type Item = &'static str;
57
58 fn next(&mut self) -> Option<Self::Item> {
59 match self {
60 Self::OneAtATime(cases) => cases.next().map(|(subject, _)| *subject),
61 Self::Together(cases) => cases.next().map(|(subject, _)| *subject),
62 }
63 }
64}
65
66pub struct BenchGroup<'routine> {
68 group: &'static str,
69 cases: BenchCases<'routine>,
70}
71
72impl<'routine> BenchGroup<'routine> {
73 pub const fn new(group: &'static str, cases: BenchCases<'routine>) -> Self {
75 Self { group, cases }
76 }
77
78 pub const fn group(&self) -> &'static str {
80 self.group
81 }
82
83 pub fn cases(self) -> BenchCases<'routine> {
85 self.cases
86 }
87
88 pub const fn stated(&self) -> &BenchCases<'routine> {
90 &self.cases
91 }
92}
93
94#[derive(Default)]
96pub struct BenchStated<'routine> {
97 groups: Vec<BenchGroup<'routine>>,
98}
99
100impl<'routine> BenchStated<'routine> {
101 pub const fn new() -> Self {
103 Self { groups: Vec::new() }
104 }
105
106 #[must_use]
108 pub fn group(mut self, group: BenchGroup<'routine>) -> Self {
109 self.groups.push(group);
110
111 self
112 }
113
114 #[must_use]
116 pub fn then(mut self, next: Self) -> Self {
117 self.groups.extend(next.groups);
118
119 self
120 }
121
122 pub fn groups(&self) -> impl Iterator<Item = &BenchGroup<'routine>> {
124 self.groups.iter()
125 }
126
127 pub fn into_groups(self) -> impl Iterator<Item = BenchGroup<'routine>> {
129 self.groups.into_iter()
130 }
131}