Skip to main content

broccoli_server_sdk/types/
evaluate.rs

1use serde::{Deserialize, Serialize};
2
3use super::submission::SourceFile;
4use super::verdict::Verdict;
5
6/// Fully resolved language config for one submission.
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct ResolvedLanguage {
9    pub compile_cmd: Option<Vec<String>>,
10    pub run_cmd: Vec<String>,
11    pub source_filename: String,
12    pub binary_name: String,
13}
14
15/// Contest/plugin-facing input for starting evaluation of one test case.
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct StartEvaluateCaseInput {
18    pub problem_id: i32,
19    pub test_case_id: i32,
20    pub solution_source: Vec<SourceFile>,
21    pub solution_language: String,
22    pub time_limit_ms: i32,
23    pub memory_limit_kb: i32,
24}
25
26/// Server-enriched input forwarded to the evaluator plugin.
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct BuildEvalOpsInput {
29    pub problem_id: i32,
30    pub test_case_id: i32,
31    pub solution_source: Vec<SourceFile>,
32    pub solution_language: String,
33    pub time_limit_ms: i32,
34    pub memory_limit_kb: i32,
35
36    /// Test case input (stdin content). Server-enriched.
37    #[serde(default)]
38    pub test_input: String,
39    /// Expected output for checker. Server-enriched.
40    #[serde(default)]
41    pub expected_output: String,
42    /// Checker format name (e.g. "exact", "tokens"). Server-enriched.
43    #[serde(default)]
44    pub checker_format: Option<String>,
45    /// Opaque checker config blob. Server-enriched.
46    #[serde(default)]
47    pub checker_config: Option<serde_json::Value>,
48    /// Checker source files (for custom/testlib checkers). Server-enriched.
49    #[serde(default)]
50    pub checker_source: Option<Vec<SourceFile>>,
51}
52
53/// Input for start_evaluate_batch host function.
54#[derive(Debug, Clone, Serialize, Deserialize)]
55pub struct StartEvaluateBatchInput {
56    pub problem_type: String,
57    pub test_cases: Vec<StartEvaluateCaseInput>,
58}
59
60/// Verdict for a single test case, returned by evaluator's evaluate function.
61#[derive(Debug, Clone, Serialize, Deserialize)]
62pub struct TestCaseVerdict {
63    pub test_case_id: i32,
64    pub verdict: Verdict,
65    pub score: f64,
66    /// Time used, in milliseconds.
67    pub time_used_ms: Option<i64>,
68    /// Memory used, in kilobytes.
69    pub memory_used_kb: Option<i64>,
70    pub message: Option<String>,
71    #[serde(default)]
72    pub stdout: Option<String>,
73    #[serde(default)]
74    pub stderr: Option<String>,
75}
76
77impl TestCaseVerdict {
78    /// Convenience constructor: Accepted with default time/memory.
79    pub fn accepted(tc_id: i32) -> Self {
80        Self {
81            test_case_id: tc_id,
82            verdict: Verdict::Accepted,
83            score: 1.0,
84            time_used_ms: Some(100),
85            memory_used_kb: Some(1024),
86            message: None,
87            stdout: None,
88            stderr: None,
89        }
90    }
91
92    /// Convenience constructor: WrongAnswer with default time/memory.
93    pub fn wrong_answer(tc_id: i32) -> Self {
94        Self {
95            test_case_id: tc_id,
96            verdict: Verdict::WrongAnswer,
97            score: 0.0,
98            time_used_ms: Some(50),
99            memory_used_kb: Some(512),
100            message: Some("Wrong answer".into()),
101            stdout: None,
102            stderr: None,
103        }
104    }
105
106    /// Convenience constructor: TimeLimitExceeded.
107    pub fn tle(tc_id: i32) -> Self {
108        Self {
109            test_case_id: tc_id,
110            verdict: Verdict::TimeLimitExceeded,
111            score: 0.0,
112            time_used_ms: None,
113            memory_used_kb: Some(512),
114            message: Some("Time limit exceeded".into()),
115            stdout: None,
116            stderr: None,
117        }
118    }
119
120    /// Convenience constructor: CompileError.
121    pub fn compile_error(tc_id: i32) -> Self {
122        Self {
123            test_case_id: tc_id,
124            verdict: Verdict::CompileError,
125            score: 0.0,
126            time_used_ms: None,
127            memory_used_kb: None,
128            message: Some("Compilation failed".into()),
129            stdout: None,
130            stderr: None,
131        }
132    }
133
134    /// Convenience constructor: SystemError.
135    pub fn system_error(tc_id: i32) -> Self {
136        Self {
137            test_case_id: tc_id,
138            verdict: Verdict::SystemError,
139            score: 0.0,
140            time_used_ms: None,
141            memory_used_kb: None,
142            message: Some("System error".into()),
143            stdout: None,
144            stderr: None,
145        }
146    }
147}