codspeed-bencher-compat 4.7.0

Bencher compatibility layer for CodSpeed
Documentation
use codspeed::{
    codspeed::{black_box, CodSpeed, WARMUP_RUNS},
    utils::{get_formated_function_path, get_git_relative_path},
};

pub struct Bencher {
    pub bytes: u64,
    codspeed: CodSpeed,
    current_file: String,
    current_bench_path: String,
}

impl Bencher {
    pub fn set_current_file(&mut self, file: impl Into<String>) {
        self.current_file = file.into();
    }

    pub fn set_current_bench_path(&mut self, bench: impl Into<String>) {
        self.current_bench_path = bench.into();
    }

    pub fn push_group(&mut self, group: &str) {
        self.codspeed.push_group(group);
    }

    pub fn pop_group(&mut self) {
        self.codspeed.pop_group();
    }

    pub fn iter<T, F>(&mut self, mut inner: F)
    where
        F: FnMut() -> T,
    {
        let file = get_git_relative_path(self.current_file.as_str());
        let bench_path = get_formated_function_path(self.current_bench_path.as_str());
        let uri = format!("{}::{}", file.to_string_lossy(), bench_path);
        for _ in 0..WARMUP_RUNS {
            black_box(inner());
        }
        self.codspeed.start_benchmark(uri.as_str());
        let output = inner();
        self.codspeed.end_benchmark();
        black_box(output);
    }
}

impl Default for Bencher {
    fn default() -> Self {
        println!(
            "Harness: codspeed-bencher-compat v{}",
            env!("CARGO_PKG_VERSION"),
        );
        Bencher {
            bytes: 0,
            codspeed: CodSpeed::new(),
            current_file: String::new(),
            current_bench_path: String::new(),
        }
    }
}

#[macro_export]
macro_rules! benchmark_group {
    ($group_name:ident, $( $function:path ),+ $(,)*) => {
        pub fn $group_name(bencher: &mut $crate::Bencher) {
            bencher.push_group(stringify!($group_name));
            $(
                bencher.set_current_file($crate::abs_file!());
                bencher.set_current_bench_path(stringify!($function));
                $function(bencher);
            )+
            bencher.pop_group();
        }
    };
    ($group_name:ident, $($function:path,)+) => {
        benchmark_group!($group_name, $($function),+);
    };
}

#[macro_export]
macro_rules! benchmark_main {
    ($($group_name:path),+) => {
        pub fn main() {
            let mut bencher = $crate::Bencher::default();
            $(
                $group_name(&mut bencher);
            )+
        }
    };
    ($($group_name:path,)+) => {
        benchmark_main!($($group_name),+);
    };
}