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 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 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}