judge_core/
builder.rs

1use std::{fs, path::PathBuf};
2
3use crate::{
4    compiler::{Compiler, Language},
5    error::{path_not_exist, JudgeCoreError},
6    utils::copy_recursively,
7};
8
9pub enum PackageType {
10    ICPC,
11}
12
13pub struct JudgeBuilder {
14    package_type: PackageType,
15    package_path: PathBuf,
16    runtime_path: PathBuf,
17    src_language: Language,
18    src_path: PathBuf,
19    built: bool,
20}
21
22impl JudgeBuilder {
23    pub fn new(
24        package_type: PackageType,
25        package_path: PathBuf,
26        runtime_path: PathBuf,
27        src_language: Language,
28        src_path: PathBuf,
29    ) -> Self {
30        Self {
31            package_type,
32            package_path,
33            runtime_path,
34            src_language,
35            src_path,
36            built: false,
37        }
38    }
39
40    pub fn build(&mut self) -> Result<(), JudgeCoreError> {
41        match self.package_type {
42            PackageType::ICPC => self.build_icpc(),
43        }
44    }
45
46    fn build_icpc(&mut self) -> Result<(), JudgeCoreError> {
47        fs::create_dir_all(self.runtime_path.clone())?;
48        // copy checker to runtime path
49        let package_output_validators_path = self.package_path.join("output_validators");
50        if package_output_validators_path.exists() {
51            log::warn!("Output validators found, but not supported yet");
52        } else {
53            log::info!("No output validators found, using default checker");
54        }
55        // copy testcases to runtime path
56        let package_testcases_path = self.package_path.join("data");
57        let runtime_testcases_path = self.runtime_path.join("data");
58        if package_testcases_path.exists() {
59            copy_recursively(&package_testcases_path, &runtime_testcases_path)?;
60        } else {
61            return Err(path_not_exist(&package_testcases_path));
62        }
63        if self.src_path.exists() {
64            let compiler = Compiler::new(self.src_language, vec![]);
65            compiler.compile(&self.src_path, &self.runtime_path.join("program"))?;
66        } else {
67            return Err(path_not_exist(&self.src_path));
68        }
69
70        self.built = true;
71        Ok(())
72    }
73}
74
75#[cfg(test)]
76pub mod builder {
77    use super::{JudgeBuilder, Language, PackageType};
78    use std::path::PathBuf;
79
80    fn init() {
81        let _ = env_logger::builder().is_test(true).try_init();
82    }
83
84    #[test]
85    fn test_build_icpc() {
86        init();
87        let mut builder = JudgeBuilder::new(
88            PackageType::ICPC,
89            PathBuf::from("../test-collection/packages/icpc/hello_world"),
90            PathBuf::from("../tmp/icpc"),
91            Language::Cpp,
92            PathBuf::from("../test-collection/src/programs/infinite_loop.cpp"),
93        );
94        match builder.build() {
95            Ok(_) => {
96                log::info!("Build success");
97            }
98            Err(e) => panic!("{:?}", e),
99        }
100    }
101}