use std::{fs::create_dir_all, path::PathBuf, time::Duration}; use anyhow::Result; use crate::{ compile::{compile, Language}, config::{JudgeOptions, TestCase}, exec::execute, judge::{JudgeResult, JudgeStatus}, }; pub async fn run_test_cases( language: Language, workspace: B, source_file_path: B, options: JudgeOptions, test_cases: Vec<(C, C)>, clean: bool, ) -> Result> where B: Into, C: Into, { let workspace: PathBuf = workspace.into(); if !workspace.exists() { create_dir_all(&workspace)?; } let source_file_path = Into::::into(source_file_path) .to_string_lossy() .to_string(); let exec_path = match &language { Language::Python => PathBuf::from("python"), _ => workspace.join("out"), }; if let Err(e) = compile( language, workspace.clone(), &source_file_path, exec_path.to_string_lossy(), ) .await { return Ok(vec![JudgeResult { status: JudgeStatus::CompileError { message: e.to_string(), }, time_used: Duration::default(), memory_used: 0, }]); }; let args = vec![source_file_path.as_str()]; let args = match language { Language::Python => Some(&args), _ => None, } .map(|v| &**v); let mut results = vec![]; for (input_file, expected_output_file) in test_cases { results.push( execute( &workspace, exec_path.to_string_lossy(), args, &options, TestCase { input_file: input_file.into(), expected_output_file: expected_output_file.into(), }, workspace.join("test.out"), ) .await?, ); } if clean { if let Err(e) = std::fs::remove_dir_all(workspace) { anyhow::bail!("Failed to remove workspace: {}", e); } } Ok(results) }