algohub_server/models/
problem.rs

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}