From 66dcafd389474476f0a7cb998de5fbc34fcd14c9 Mon Sep 17 00:00:00 2001 From: MeiK Date: Fri, 27 Mar 2020 18:43:03 +0800 Subject: [PATCH] Update --- Cargo.toml | 2 + example/config.yml | 10 ++--- src/config.rs | 104 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 22 +++++++++- src/runner.rs | 11 ++--- 5 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 src/config.rs diff --git a/Cargo.toml b/Cargo.toml index f0dcd0d..0bcc657 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,5 @@ edition = "2018" [dependencies] libc = "0.2" +handlebars = "3.0.1" +yaml-rust = "0.4" diff --git a/example/config.yml b/example/config.yml index 10509a3..8d200b7 100644 --- a/example/config.yml +++ b/example/config.yml @@ -16,12 +16,12 @@ judge_type: standard # standard / special # language: cpp extra_files: - hello.txt -# code: -# file: main.c -# language: c code: - file: main.cpp - language: cpp + file: main.c + language: c +# code: +# file: main.cpp +# language: cpp # code: # file: main.py # language: python diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..d68a86b --- /dev/null +++ b/src/config.rs @@ -0,0 +1,104 @@ +use std::result; +use yaml_rust::{ScanError, Yaml, YamlLoader}; + +#[derive(Debug)] +pub enum Error { + YamlScanError(ScanError), + YamlParseError(String), +} + +pub type Result = result::Result; + +pub struct LanguageConfig { + pub language: String, + pub version: String, + pub compile_command: String, + pub run_command: String, +} + +pub struct Config { + pub languages: Vec, +} + +impl Config { + fn load_yaml(yaml: &str) -> Result { + let docs = match YamlLoader::load_from_str(yaml) { + Ok(value) => value, + Err(err) => return Err(Error::YamlScanError(err)), + }; + let doc = &docs[0]; + + // 读取语言配置 + let mut languages: Vec = vec![]; + let yaml_languages = match &doc["languages"] { + Yaml::Array(value) => value, + Yaml::BadValue => { + return Err(Error::YamlParseError( + "解析错误,无法解析到 languages 字段".to_string(), + )) + } + _ => { + return Err(Error::YamlParseError( + "解析错误,languages 字段的类型应该为 Array".to_string(), + )) + } + }; + for yaml_language in yaml_languages { + let language = match &yaml_language["language"] { + Yaml::String(value) => value.clone(), + _ => { + return Err(Error::YamlParseError( + "解析错误,language 字段的类型应该为 String".to_string(), + )) + } + }; + let version = match &yaml_language["version"] { + Yaml::String(value) => value.clone(), + _ => { + return Err(Error::YamlParseError( + "version 字段的类型应该为 String".to_string(), + )) + } + }; + let compile_command = match &yaml_language["compile_command"] { + Yaml::String(value) => value.clone(), + _ => { + return Err(Error::YamlParseError( + "compile_command 字段的类型应该为 String".to_string(), + )) + } + }; + let run_command = match &yaml_language["run_command"] { + Yaml::String(value) => value.clone(), + _ => { + return Err(Error::YamlParseError( + "run_command 字段的类型应该为 String".to_string(), + )) + } + }; + languages.push(LanguageConfig { + language, + version, + compile_command, + run_command, + }); + } + + Ok(Config { languages }) + } + pub fn default() -> Result { + let config_yaml = " +languages: + - language: c + version: 7.5.0 + compile_command: /usr/bin/gcc {{filename}} -o a.out + run_command: ./a.out + - language: python + version: 3.6.9 + compile_command: /usr/bin/python3 -m compileall {{filename}} + run_command: /use/bin/python3 {{filename}} + "; + let config = Config::load_yaml(config_yaml)?; + Ok(config) + } +} diff --git a/src/main.rs b/src/main.rs index 0906953..ba31e40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,28 @@ extern crate libc; +use std::collections::BTreeMap; +use handlebars::Handlebars; + mod runner; +mod config; fn main() { + let mut handlebars = Handlebars::new(); + let source = "hello {{world}}"; + let _ = handlebars.register_template_string("t1", source); + let mut data = BTreeMap::new(); + data.insert("hello".to_string(), "你好".to_string()); + data.insert("world".to_string(), "世界!".to_string()); + println!("{}", handlebars.render("t1", &data).unwrap()); + + let _config = match config::Config::default() { + Ok(value) => value, + Err(err) => { + println!("{:?}", err); + return + } + }; + process(); } @@ -11,7 +31,7 @@ fn process() { unsafe { pid = libc::fork(); } - let mut run_configs = runner::RunConfigs { + let mut run_configs = runner::JudgeConfigs { exec_file: "/usr/bin/python3".to_string(), exec_args: vec![ "/usr/bin/python3".to_string(), diff --git a/src/runner.rs b/src/runner.rs index c543bc8..affb9af 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -29,7 +29,7 @@ pub enum TestCaseResult { SystemError(String), } -pub struct RunConfigs { +pub struct JudgeConfigs { pub exec_file: String, pub exec_args: Vec, pub test_cases: Vec, @@ -41,7 +41,7 @@ pub struct ExecArgs { pub envp: *const *const libc::c_char, } -impl RunConfigs { +impl JudgeConfigs { /** * 为 exec 函数生成参数 * 涉及到 Rust 到 C 的内存转换,此过程是内存不安全的 @@ -74,11 +74,12 @@ impl RunConfigs { mem::forget(env); mem::forget(exec_file); mem::forget(exec_args); - return Ok(ExecArgs { + + Ok(ExecArgs { pathname: exec_file_ptr, argv: exec_args_ptr, envp: env_ptr, - }); + }) } } @@ -88,7 +89,7 @@ mod tests { #[test] fn test_base() { - let run_args = RunConfigs { + let run_args = JudgeConfigs { exec_file: "/bin/echo".to_string(), exec_args: vec![ "/bin/echo".to_string(),