mirror of
https://github.com/MeiK2333/river.git
synced 2025-11-04 14:49:40 +08:00
Update
This commit is contained in:
parent
3a42503ae8
commit
66dcafd389
@ -8,3 +8,5 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
handlebars = "3.0.1"
|
||||
yaml-rust = "0.4"
|
||||
|
||||
@ -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
|
||||
|
||||
104
src/config.rs
Normal file
104
src/config.rs
Normal file
@ -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<T> = result::Result<T, Error>;
|
||||
|
||||
pub struct LanguageConfig {
|
||||
pub language: String,
|
||||
pub version: String,
|
||||
pub compile_command: String,
|
||||
pub run_command: String,
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
pub languages: Vec<LanguageConfig>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
fn load_yaml(yaml: &str) -> Result<Config> {
|
||||
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<LanguageConfig> = 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<Config> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
22
src/main.rs
22
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(),
|
||||
|
||||
@ -29,7 +29,7 @@ pub enum TestCaseResult {
|
||||
SystemError(String),
|
||||
}
|
||||
|
||||
pub struct RunConfigs {
|
||||
pub struct JudgeConfigs {
|
||||
pub exec_file: String,
|
||||
pub exec_args: Vec<String>,
|
||||
pub test_cases: Vec<TestCase>,
|
||||
@ -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(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user