use serde::{Deserialize, Serialize};
use super::File;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExecResult {
pub stdout: String,
pub stderr: String,
pub output: String,
pub code: Option<isize>,
pub signal: Option<String>,
}
impl ExecResult {
pub fn is_ok(&self) -> bool {
self.code.is_some() && self.code.unwrap() == 0
}
pub fn is_err(&self) -> bool {
self.code.is_some() && self.code.unwrap() != 0
}
}
#[doc(hidden)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RawExecResponse {
pub language: String,
pub version: String,
pub run: ExecResult,
pub compile: Option<ExecResult>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ExecResponse {
pub language: String,
pub version: String,
pub run: ExecResult,
pub compile: Option<ExecResult>,
pub status: u16,
}
impl ExecResponse {
pub fn is_ok(&self) -> bool {
self.status == 200
}
pub fn is_err(&self) -> bool {
self.status != 200
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Executor {
pub language: String,
pub version: String,
pub files: Vec<File>,
pub stdin: String,
pub args: Vec<String>,
pub compile_timeout: isize,
pub run_timeout: isize,
pub compile_memory_limit: isize,
pub run_memory_limit: isize,
}
impl Default for Executor {
fn default() -> Self {
Self::new()
}
}
impl Executor {
pub fn new() -> Self {
Self {
language: String::new(),
version: String::from("*"),
files: vec![],
stdin: String::new(),
args: vec![],
compile_timeout: 10000,
run_timeout: 3000,
compile_memory_limit: -1,
run_memory_limit: -1,
}
}
pub fn reset(&mut self) {
self.language = String::new();
self.version = String::from("*");
self.files = vec![];
self.stdin = String::new();
self.args = vec![];
self.compile_timeout = 10000;
self.run_timeout = 3000;
self.compile_memory_limit = -1;
self.run_memory_limit = -1;
}
#[must_use]
pub fn set_language(mut self, language: &str) -> Self {
self.language = language.to_lowercase();
self
}
#[must_use]
pub fn set_version(mut self, version: &str) -> Self {
self.version = version.to_string();
self
}
#[must_use]
pub fn add_file(mut self, file: File) -> Self {
self.files.push(file);
self
}
#[must_use]
pub fn add_files(mut self, files: Vec<File>) -> Self {
self.files.extend(files);
self
}
pub fn set_files(&mut self, files: Vec<File>) {
self.files = files;
}
#[must_use]
pub fn set_stdin(mut self, stdin: &str) -> Self {
self.stdin = stdin.to_string();
self
}
#[must_use]
pub fn add_arg(mut self, arg: &str) -> Self {
self.args.push(arg.to_string());
self
}
#[must_use]
pub fn add_args(mut self, args: Vec<&str>) -> Self {
self.args.extend(args.iter().map(|a| a.to_string()));
self
}
pub fn set_args(&mut self, args: Vec<&str>) {
self.args = args.iter().map(|a| a.to_string()).collect();
}
#[must_use]
pub fn set_compile_timeout(mut self, timeout: isize) -> Self {
self.compile_timeout = timeout;
self
}
#[must_use]
pub fn set_run_timeout(mut self, timeout: isize) -> Self {
self.run_timeout = timeout;
self
}
#[must_use]
pub fn set_compile_memory_limit(mut self, limit: isize) -> Self {
self.compile_memory_limit = limit;
self
}
#[must_use]
pub fn set_run_memory_limit(mut self, limit: isize) -> Self {
self.run_memory_limit = limit;
self
}
}
#[cfg(test)]
mod test_execution_result {
use super::ExecResponse;
use super::ExecResult;
fn generate_result(stdout: &str, stderr: &str, code: isize) -> ExecResult {
ExecResult {
stdout: stdout.to_string(),
stderr: stderr.to_string(),
output: format!("{}\n{}", stdout, stderr),
code: Some(code),
signal: None,
}
}
fn generate_response(status: u16) -> ExecResponse {
ExecResponse {
language: "rust".to_string(),
version: "1.50.0".to_string(),
run: generate_result("Be unique.", "", 0),
compile: None,
status,
}
}
#[test]
fn test_response_is_ok() {
let response = generate_response(200);
assert!(response.is_ok());
assert!(!response.is_err());
}
#[test]
fn test_response_is_err() {
let response = generate_response(400);
assert!(!response.is_ok());
assert!(response.is_err());
}
#[test]
fn test_result_is_ok() {
let result = generate_result("Hello, world", "", 0);
assert!(result.is_ok());
assert!(!result.is_err());
}
#[test]
fn test_result_is_err() {
let result = generate_result("", "Error!", 1);
assert!(!result.is_ok());
assert!(result.is_err());
}
#[test]
fn test_is_err_with_stdout() {
let result = generate_result("Hello, world", "Error!", 1);
assert!(!result.is_ok());
assert!(result.is_err());
}
}