1use serde::{Deserialize, Serialize};
2use surrealdb::sql::Thing;
3
4use super::UserRecordId;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Sample {
8 pub input: String,
9 pub output: String,
10}
11
12#[derive(Serialize, Deserialize, Clone)]
13pub struct TestCase {
14 pub input: Thing,
15 pub output: Thing,
16}
17
18impl From<UserTestCase<'_>> for TestCase {
19 fn from(value: UserTestCase<'_>) -> Self {
20 TestCase {
21 input: Thing::from(("asset", value.input)),
22 output: Thing::from(("asset", value.output)),
23 }
24 }
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
28#[serde(rename_all = "snake_case")]
29pub enum ProblemVisibility {
30 ContestOnly,
31 Public,
32 Private,
33 Internal,
34}
35
36#[derive(Clone, Serialize, Deserialize)]
37pub struct Problem {
38 pub id: Option<Thing>,
39
40 pub title: String,
41 pub description: String,
42 pub input: Option<String>,
43 pub output: Option<String>,
44 pub samples: Vec<Sample>,
45 pub hint: Option<String>,
46
47 pub time_limit: u64,
48 pub memory_limit: u64,
49 pub test_cases: Vec<TestCase>,
50
51 pub creator: Thing,
52 pub owner: Thing,
53 pub categories: Vec<String>,
54 pub tags: Vec<String>,
55
56 pub visibility: ProblemVisibility,
57 pub contest: Option<Thing>,
58
59 pub created_at: chrono::NaiveDateTime,
60 pub updated_at: chrono::NaiveDateTime,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize)]
64pub struct UserTestCase<'r> {
65 pub input: &'r str,
66 pub output: &'r str,
67}
68
69#[derive(Serialize, Deserialize)]
70#[serde(crate = "rocket::serde")]
71pub struct CreateProblem<'r> {
72 pub id: &'r str,
73 pub token: &'r str,
74
75 pub title: &'r str,
76 pub description: String,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub input: Option<String>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub output: Option<String>,
81 pub samples: Vec<Sample>,
82 #[serde(skip_serializing_if = "Option::is_none")]
83 pub hint: Option<String>,
84
85 pub owner: UserRecordId,
86 pub time_limit: u64,
87 pub memory_limit: u64,
88 pub test_cases: Vec<UserTestCase<'r>>,
89
90 pub categories: Vec<String>,
91 pub tags: Vec<String>,
92
93 pub visibility: ProblemVisibility,
94}
95
96impl From<CreateProblem<'_>> for Problem {
97 fn from(val: CreateProblem<'_>) -> Self {
98 Problem {
99 id: None,
100 title: val.title.to_string(),
101 description: val.description.to_string(),
102 input: val.input,
103 output: val.output,
104 samples: val.samples,
105 hint: val.hint,
106 time_limit: val.time_limit,
107 memory_limit: val.memory_limit,
108 test_cases: val.test_cases.into_iter().map(Into::into).collect(),
109 creator: ("account", val.id).into(),
110 owner: val.owner.into(),
111 categories: val.categories,
112 tags: val.tags,
113 visibility: val.visibility,
114 contest: None,
115 created_at: chrono::Local::now().naive_local(),
116 updated_at: chrono::Local::now().naive_local(),
117 }
118 }
119}
120
121#[derive(Debug, Clone, Serialize, Deserialize)]
122pub struct OwnedUserTestCase {
123 pub input: String,
124 pub output: String,
125}
126
127impl From<TestCase> for OwnedUserTestCase {
128 fn from(value: TestCase) -> Self {
129 OwnedUserTestCase {
130 input: value.input.id.to_string(),
131 output: value.output.id.to_string(),
132 }
133 }
134}
135
136#[derive(Debug, Deserialize, Serialize)]
137pub struct UserProblem {
138 pub id: String,
139
140 pub title: String,
141 pub description: String,
142 pub input: Option<String>,
143 pub output: Option<String>,
144 pub samples: Vec<Sample>,
145 pub hint: Option<String>,
146
147 pub time_limit: u64,
148 pub memory_limit: u64,
149 pub test_cases: Vec<OwnedUserTestCase>,
150
151 pub creator: String,
152 pub owner: UserRecordId,
153 pub categories: Vec<String>,
154 pub tags: Vec<String>,
155
156 pub visibility: ProblemVisibility,
157
158 pub created_at: chrono::NaiveDateTime,
159 pub updated_at: chrono::NaiveDateTime,
160}
161
162impl From<Problem> for UserProblem {
163 fn from(value: Problem) -> Self {
164 UserProblem {
165 id: value.id.unwrap().id.to_string(),
166 title: value.title,
167 description: value.description,
168 input: value.input,
169 output: value.output,
170 samples: value.samples,
171 hint: value.hint,
172 time_limit: value.time_limit,
173 memory_limit: value.memory_limit,
174 test_cases: value.test_cases.into_iter().map(Into::into).collect(),
175 creator: value.creator.id.to_string(),
176 owner: value.owner.into(),
177 categories: value.categories,
178 tags: value.tags,
179 visibility: value.visibility,
180 created_at: value.created_at,
181 updated_at: value.updated_at,
182 }
183 }
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct ServerTestCase {
188 pub input: String,
189 pub output: String,
190}