use colci::Color;
use crate::model::ExecutionErrorResponse;
use crate::printer::{decorator::bold_text, Printer, NEW_LINE};
use crate::{icon::Icon, model::SubmissionResponse, Either};
#[derive(Debug)]
pub struct SubmitExecutionResult {
submission_response: SubmissionResponse,
}
impl Printer for SubmitExecutionResult {
fn is_error(&self) -> bool {
self.submission_response.is_error()
}
fn buffer(&self) -> String {
if self.is_error() {
self.error_buffer()
} else {
self.success_buffer()
}
}
}
impl SubmitExecutionResult {
pub fn new(submission_response: SubmissionResponse) -> Self {
Self {
submission_response,
}
}
fn error_buffer(&self) -> String {
let error_buffer = self.runtime_error_buffer()
+ NEW_LINE
+ NEW_LINE
+ self.compile_error_buffer().as_str();
if error_buffer.trim().is_empty() {
self.wrong_answer_buffer()
} else {
error_buffer
}
}
fn runtime_error_buffer(&self) -> String {
if !self.submission_response.has_runtime_error() {
return NEW_LINE.to_owned();
}
self.submission_response.status_msg.to_owned()
}
fn compile_error_buffer(&self) -> String {
if !self.submission_response.has_compile_error() {
return NEW_LINE.to_owned();
}
self.submission_response
.full_compile_error
.to_owned()
.unwrap_or_default()
}
fn wrong_answer_buffer(&self) -> String {
let mut buffer = String::new();
buffer.push_str(&bold_text(
&Color::Red(&format!(
"\n{} Wrong Answer: ({})\n\n",
Icon::_No.to_string(),
self.total_cases_ratio_buffer(&self.submission_response)
))
.make(),
));
buffer.push_str(&self.last_test_case_buffer());
buffer.push_str(&Color::Red(&self.get_metas()).make());
buffer
}
fn last_test_case_buffer(&self) -> String {
let mut buffer = String::new();
match (
&self.submission_response.input,
&self.submission_response.code_output,
&self.submission_response.expected_output,
) {
(
Some(Either::String(input)),
Some(Either::String(ans)),
Some(Either::String(exp_ans)),
) => {
let mut test_case = String::new();
test_case.push_str(&Color::Red("Last test case:\n").make());
test_case.push_str(&format!(
"\tInput: \n\t\t{}\n",
input.replace('\n', "\n\t\t")
));
test_case.push_str(&format!("\n\tOutput: {}\n", ans));
test_case.push_str(&format!("\tExpected: {}\n\n", exp_ans));
buffer.push_str(test_case.as_str());
}
_ => {}
}
buffer
}
fn success_buffer(&self) -> String {
let mut buffer = String::new();
buffer.push_str(&bold_text(
&Color::Green(&format!(
"{} Accepted: ({})\n\n",
Icon::Yes.to_string(),
self.total_cases_ratio_buffer(&self.submission_response)
))
.make(),
));
buffer.push_str(&self.last_test_case_buffer());
buffer.push_str(&Color::Green(&self.get_metas()).make());
buffer
}
fn get_metas(&self) -> String {
if self.is_error() {
return NEW_LINE.to_string();
}
let memory_percentile = self
.submission_response
.memory_percentile
.unwrap_or(0.0)
.to_string();
let runtime_percentile = self
.submission_response
.runtime_percentile
.unwrap_or(0.0)
.to_string();
let metas = vec![
"Memory: ".to_string() + self.submission_response.status_memory.as_str(),
"Memory %ile: ".to_string() + memory_percentile.as_str(),
"Runtime: ".to_string() + self.submission_response.status_runtime.as_str(),
"Runtime %ile: ".to_string() + runtime_percentile.as_str(),
"\n\n".to_string(),
];
metas.join("\n")
}
}
#[cfg(test)]
mod tests {
use super::{Printer, SubmitExecutionResult};
use crate::model::SubmissionResponse;
use serde_json::from_value;
#[test]
fn print_submit_wrong_answer() {
let json_value = serde_json::from_str(
r#"{
"status_code": 11,
"lang": "python3",
"run_success": true,
"status_runtime": "N/A",
"memory": 16468000,
"question_id": "10",
"elapsed_time": 65,
"compare_result": "1110011111111111100011110100100011010111111111111111111101110111111111111111111111110111111110100111010111111111111111011101111111110011111111111111111110101101110010111011011101111101111111110111101011101111101111111111111101101110110111101110011111101001111110110110101101110011001111111111111111001110000010110111111111111110111110111110011111001001010",
"code_output": "false",
"std_output": "",
"last_testcase": "\"aab\"\n\"c*a*b\"",
"expected_output": "true",
"task_finish_time": 1694277425292,
"task_name": "judger.judgetask.Judge",
"finished": true,
"total_correct": 277,
"total_testcases": 355,
"runtime_percentile": null,
"status_memory": "N/A",
"memory_percentile": null,
"pretty_lang": "Python3",
"submission_id": "1044868319",
"input_formatted": "\"aab\", \"c*a*b\"",
"input": "\"aab\"\n\"c*a*b\"",
"status_msg": "Wrong Answer",
"state": "SUCCESS"
}"#
)
.unwrap();
let response = from_value::<SubmissionResponse>(json_value).unwrap().into();
let result = SubmitExecutionResult::new(response);
result.print();
assert!(1 == 1);
}
#[test]
fn print_submit_accepted() {
let json_value = serde_json::from_str(
r#"{
"status_code": 10,
"lang": "rust",
"run_success": true,
"status_runtime": "0 ms",
"memory": 1928000,
"question_id": "10",
"elapsed_time": 10,
"compare_result": "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
"code_output": "",
"std_output": "",
"last_testcase": "",
"expected_output": "",
"task_finish_time": 1694280355711,
"task_name": "judger.judgetask.Judge",
"finished": true,
"total_correct": 355,
"total_testcases": 355,
"runtime_percentile": 100,
"status_memory": "1.9 MB",
"memory_percentile": 91.83670000000001,
"pretty_lang": "Rust",
"submission_id": "1044907055",
"status_msg": "Accepted",
"state": "SUCCESS"
}"#
)
.unwrap();
let response = from_value::<SubmissionResponse>(json_value).unwrap().into();
let result = SubmitExecutionResult::new(response);
result.print();
assert!(1 == 1);
}
#[test]
fn print_submit_wrong_answer_seq() {
let json_value = serde_json::from_str(
r#"{
"status_code": 11,
"lang": "java",
"run_success": true,
"status_runtime": "N/A",
"memory": 44740000,
"display_runtime": "261",
"question_id": "15",
"elapsed_time": 467,
"compare_result": "111111111111111111110010011100110000111100001101000100000010111101100110011101001001000000010101101000000000000001111100001000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100",
"code_output": "[[-2,-1,3],[-2,0,2]]",
"std_output": "",
"last_testcase": "[3,0,-2,-1,1,2]",
"expected_output": "[[-2,-1,3],[-2,0,2],[-1,0,1]]",
"task_finish_time": 1694280912080,
"task_name": "judger.judgetask.Judge",
"finished": true,
"total_correct": 63,
"total_testcases": 312,
"runtime_percentile": null,
"status_memory": "N/A",
"memory_percentile": null,
"pretty_lang": "Java",
"submission_id": "1044914848",
"input_formatted": "[3,0,-2,-1,1,2]",
"input": "[3,0,-2,-1,1,2]",
"status_msg": "Wrong Answer",
"state": "SUCCESS"
}"#
)
.unwrap();
let response = from_value::<SubmissionResponse>(json_value).unwrap().into();
let result = SubmitExecutionResult::new(response);
result.print();
assert!(1 == 1);
}
}