codspeed_divan_compat_walltime/counter/
mod.rs1use std::any::Any;
29
30mod any_counter;
31mod collection;
32mod into_counter;
33mod sealed;
34mod uint;
35
36pub(crate) use self::{
37 any_counter::{AnyCounter, KnownCounterKind},
38 collection::{CounterCollection, CounterSet},
39 sealed::Sealed,
40 uint::{AsCountUInt, CountUInt, MaxCountUInt},
41};
42pub use into_counter::IntoCounter;
43
44#[doc(alias = "throughput")]
53pub trait Counter: Sized + Any + Sealed {}
54
55#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
57pub struct BytesCount {
58 count: MaxCountUInt,
59}
60
61#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
67pub struct CharsCount {
68 count: MaxCountUInt,
69}
70
71#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
77pub struct CyclesCount {
78 count: MaxCountUInt,
79}
80
81#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
83pub struct ItemsCount {
84 count: MaxCountUInt,
85}
86
87impl Sealed for BytesCount {}
88impl Sealed for CharsCount {}
89impl Sealed for CyclesCount {}
90impl Sealed for ItemsCount {}
91
92impl Counter for BytesCount {}
93impl Counter for CharsCount {}
94impl Counter for CyclesCount {}
95impl Counter for ItemsCount {}
96
97impl<C: AsCountUInt> From<C> for BytesCount {
98 #[inline]
99 fn from(count: C) -> Self {
100 Self::new(count.as_max_uint())
101 }
102}
103
104impl<C: AsCountUInt> From<C> for CharsCount {
105 #[inline]
106 fn from(count: C) -> Self {
107 Self::new(count.as_max_uint())
108 }
109}
110
111impl<C: AsCountUInt> From<C> for CyclesCount {
112 #[inline]
113 fn from(count: C) -> Self {
114 Self::new(count.as_max_uint())
115 }
116}
117
118impl<C: AsCountUInt> From<C> for ItemsCount {
119 #[inline]
120 fn from(count: C) -> Self {
121 Self::new(count.as_max_uint())
122 }
123}
124
125impl BytesCount {
126 #[inline]
128 pub fn new<N: CountUInt>(count: N) -> Self {
129 Self { count: count.into_max_uint() }
130 }
131
132 #[inline]
134 #[doc(alias = "size_of")]
135 pub const fn of<T>() -> Self {
136 Self { count: size_of::<T>() as MaxCountUInt }
137 }
138
139 #[inline]
141 #[doc(alias = "size_of")]
142 pub const fn of_many<T>(n: usize) -> Self {
143 match (size_of::<T>() as MaxCountUInt).checked_mul(n as MaxCountUInt) {
144 Some(count) => Self { count },
145 None => panic!("overflow"),
146 }
147 }
148
149 #[inline]
151 #[doc(alias = "size_of_val")]
152 pub fn of_val<T: ?Sized>(val: &T) -> Self {
153 Self { count: size_of_val(val) as MaxCountUInt }
155 }
156
157 #[inline]
159 pub fn of_iter<T, I>(iter: I) -> Self
160 where
161 I: IntoIterator<Item = T>,
162 {
163 Self::of_many::<T>(iter.into_iter().count())
164 }
165
166 #[inline]
174 pub fn of_str<S: ?Sized + AsRef<str>>(s: &S) -> Self {
175 Self::of_val(s.as_ref())
176 }
177
178 #[inline]
184 pub fn of_slice<T, S: ?Sized + AsRef<[T]>>(s: &S) -> Self {
185 Self::of_val(s.as_ref())
186 }
187}
188
189macro_rules! type_bytes {
190 ($ty:ident) => {
191 #[doc = concat!("[`", stringify!($ty), "`s](", stringify!($ty), ").")]
193 #[inline]
194 pub const fn $ty(n: usize) -> Self {
195 Self::of_many::<$ty>(n)
196 }
197 };
198}
199
200impl BytesCount {
202 type_bytes!(f32);
203 type_bytes!(f64);
204
205 type_bytes!(i8);
206 type_bytes!(u8);
207 type_bytes!(i16);
208 type_bytes!(u16);
209 type_bytes!(i32);
210 type_bytes!(u32);
211 type_bytes!(i64);
212 type_bytes!(u64);
213 type_bytes!(i128);
214 type_bytes!(u128);
215 type_bytes!(isize);
216 type_bytes!(usize);
217}
218
219impl CharsCount {
220 #[inline]
222 pub fn new<N: CountUInt>(count: N) -> Self {
223 Self { count: count.into_max_uint() }
224 }
225
226 #[inline]
228 pub fn of_str<S: ?Sized + AsRef<str>>(s: &S) -> Self {
229 Self::new(s.as_ref().chars().count())
230 }
231}
232
233impl CyclesCount {
234 #[inline]
236 pub fn new<N: CountUInt>(count: N) -> Self {
237 Self { count: count.into_max_uint() }
238 }
239}
240
241impl ItemsCount {
242 #[inline]
244 pub fn new<N: CountUInt>(count: N) -> Self {
245 Self { count: count.into_max_uint() }
246 }
247
248 #[inline]
250 pub fn of_iter<T, I>(iter: I) -> Self
251 where
252 I: IntoIterator<Item = T>,
253 {
254 Self::new(iter.into_iter().count())
255 }
256}
257
258#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord)]
262#[non_exhaustive]
263pub enum BytesFormat {
264 #[default]
266 Decimal,
267
268 Binary,
270}
271
272#[derive(Clone, Copy)]
275pub(crate) struct PrivBytesFormat(pub BytesFormat);
276
277impl clap::ValueEnum for PrivBytesFormat {
278 fn value_variants<'a>() -> &'a [Self] {
279 &[Self(BytesFormat::Decimal), Self(BytesFormat::Binary)]
280 }
281
282 fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
283 let name = match self.0 {
284 BytesFormat::Decimal => "decimal",
285 BytesFormat::Binary => "binary",
286 };
287 Some(clap::builder::PossibleValue::new(name))
288 }
289}
290
291#[cfg(test)]
292mod tests {
293 use super::*;
294
295 mod bytes_count {
296 use super::*;
297
298 #[test]
299 fn of_iter() {
300 assert_eq!(BytesCount::of_iter::<i32, _>([1, 2, 3]), BytesCount::of_slice(&[1, 2, 3]));
301 }
302 }
303}