1use crate::result::{CaseResult, Error};
4use rayon::{prelude::*, ThreadPool, ThreadPoolBuilder};
5use std::{
6 fmt::Debug,
7 path::{Path, PathBuf},
8 sync::LazyLock,
9};
10
11const WORKER_STACK_SIZE: usize = 8 * 1024 * 1024;
16
17static POOL: LazyLock<ThreadPool> = LazyLock::new(|| {
18 ThreadPoolBuilder::new()
19 .stack_size(WORKER_STACK_SIZE)
20 .build()
21 .expect("failed to build the test case thread pool")
22});
23
24pub trait Case: Debug + Send + Sync + Sized + 'static {
28 fn description(&self) -> String {
30 "no description".to_string()
31 }
32
33 fn load(path: &Path) -> Result<Self, Error>;
37
38 fn run(self) -> Result<(), Error>;
40}
41
42#[derive(Debug)]
44pub struct Cases<T> {
45 pub test_cases: Vec<(PathBuf, T)>,
47}
48
49impl<T: Case> Cases<T> {
50 pub fn run(self) -> Vec<CaseResult> {
52 POOL.install(|| {
53 self.test_cases
54 .into_par_iter()
55 .map(|(path, case)| CaseResult::new(&path, case.description(), case.run()))
56 .collect()
57 })
58 }
59}