codeforces_api/obj/
responses.rs

1//! Contains the structs etc. which are returned by the Codeforces API
2//! following a request.
3
4use serde::{Deserialize, Serialize};
5
6#[cfg(feature = "serde_yaml")]
7use std::fmt;
8
9/// Response code returned by Codeforces API (Ok, Failed).
10///
11/// This is extracted from JSON API responses (the `status` field).
12#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
13#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
14pub enum CFResponseStatus {
15    Ok,
16    Failed,
17}
18
19#[cfg(feature = "serde_yaml")]
20impl fmt::Display for CFResponseStatus {
21    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
22    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23        match serde_yaml::to_string(self) {
24            Ok(s) => write!(f, "{}", s),
25            Err(_) => Err(fmt::Error),
26        }
27    }
28}
29
30/// Response type used internally which directly represents network responses
31/// sent back from the Codeforces API.
32///
33/// Note that using the `.get()` function on a type like
34/// [`CFUserCommand::Info`](super::requests::CFUserCommand::Info), will return
35/// a [`CFResult`] (in a result) and not this type. Internally, [`CFResponse`]
36/// is used as a wrapper to handle errors and serialization more easily.
37#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
38pub struct CFResponse {
39    pub status: CFResponseStatus,
40    pub result: Option<CFResult>,
41    pub comment: Option<String>,
42}
43
44#[cfg(feature = "serde_yaml")]
45impl fmt::Display for CFResponse {
46    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        match serde_yaml::to_string(self) {
49            Ok(s) => write!(f, "{}", s),
50            Err(_) => Err(fmt::Error),
51        }
52    }
53}
54
55/// Wrapper for all forms of result returned by the Codeforces API.
56///
57/// # Examples
58///
59/// You probably want to match on it depending on the kind of request you are
60/// making.
61///
62/// ```
63/// # use codeforces_api::requests::*;
64/// # use codeforces_api::responses::*;
65/// # let api_key = codeforces_api::TEST_API_KEY;
66/// # let api_secret = codeforces_api::TEST_API_SECRET;
67/// let x = CFContestCommand::Status {
68///     contest_id: 1485,
69///     handle: None,
70///     from: Some(1),
71///     count: Some(3),
72/// };
73///
74/// // x.get(..) will return a CFResult type. You should match on it to make
75/// // sure that it returned the type you expected.
76/// // To check which type a request should return, you can check its docs.
77/// // If the type returned is of the form `Ok(<unexpected_type>)`, then an
78/// // internal parsing issue has occurred somewhere (this should be rare).
79/// if let Ok(CFResult::CFSubmissionVec(v)) = x.get(api_key, api_secret) {
80///     // your code here
81/// }
82/// ```
83#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
84#[serde(untagged)]
85pub enum CFResult {
86    CFCommentVec(Vec<CFComment>),
87    CFBlogEntry(CFBlogEntry),
88    CFHackVec(Vec<CFHack>),
89    CFContestVec(Vec<CFContest>),
90    CFRatingChangeVec(Vec<CFRatingChange>),
91    CFContestStandings(CFContestStandings),
92    CFSubmissionVec(Vec<CFSubmission>),
93    CFProblemset(CFProblemset),
94    CFRecentActionVec(Vec<CFRecentAction>),
95    CFBlogEntryVec(Vec<CFBlogEntry>),
96    CFFriends(Vec<String>),
97    CFUserVec(Vec<CFUser>),
98}
99
100#[cfg(feature = "serde_yaml")]
101impl fmt::Display for CFResult {
102    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
103    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104        match serde_yaml::to_string(self) {
105            Ok(s) => write!(f, "{}", s),
106            Err(_) => Err(fmt::Error),
107        }
108    }
109}
110
111/// Struct representing a Codeforces
112/// [user](https://codeforces.com/apiHelp/objects#User).
113#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
114#[serde(rename_all = "camelCase")]
115pub struct CFUser {
116    pub handle: String,
117    pub email: Option<String>,
118    pub vk_id: Option<String>,
119    pub open_id: Option<String>,
120    pub first_name: Option<String>,
121    pub last_name: Option<String>,
122    pub country: Option<String>,
123    pub city: Option<String>,
124    pub organization: Option<String>,
125    pub contribution: i64,
126    pub rank: Option<String>,
127    pub rating: Option<i64>,
128    pub max_rank: Option<String>,
129    pub max_rating: Option<i64>,
130    pub last_online_time_seconds: i64,
131    pub registration_time_seconds: i64,
132    pub friend_of_count: i64,
133    pub avatar: String,
134    pub title_photo: String,
135}
136
137#[cfg(feature = "serde_yaml")]
138impl fmt::Display for CFUser {
139    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
140    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141        match serde_yaml::to_string(self) {
142            Ok(s) => write!(f, "{}", s),
143            Err(_) => Err(fmt::Error),
144        }
145    }
146}
147
148/// Struct representing a Codeforces
149/// [blog entry](https://codeforces.com/apiHelp/objects#BlogEntry).
150#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
151#[serde(rename_all = "camelCase")]
152pub struct CFBlogEntry {
153    pub id: i64,
154    pub original_locale: String,
155    pub creation_time_seconds: i64,
156    pub author_handle: String,
157    pub title: String,
158    pub content: Option<String>,
159    pub locale: String,
160    pub modification_time_seconds: i64,
161    pub allow_view_history: bool,
162    pub tags: Vec<String>,
163    pub rating: i64,
164}
165
166#[cfg(feature = "serde_yaml")]
167impl fmt::Display for CFBlogEntry {
168    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
169    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
170        match serde_yaml::to_string(self) {
171            Ok(s) => write!(f, "{}", s),
172            Err(_) => Err(fmt::Error),
173        }
174    }
175}
176
177/// Struct representing a Codeforces blog entry
178/// [comment](https://codeforces.com/apiHelp/objects#Comment).
179#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
180#[serde(rename_all = "camelCase")]
181pub struct CFComment {
182    pub id: i64,
183    pub creation_time_seconds: i64,
184    pub commentator_handle: String,
185    pub locale: String,
186    pub text: String,
187    pub parent_comment_id: Option<i64>,
188    pub rating: i64,
189}
190
191#[cfg(feature = "serde_yaml")]
192impl fmt::Display for CFComment {
193    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
194    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195        match serde_yaml::to_string(self) {
196            Ok(s) => write!(f, "{}", s),
197            Err(_) => Err(fmt::Error),
198        }
199    }
200}
201
202/// Struct representing a Codeforces
203/// [recent action](https://codeforces.com/apiHelp/objects#RecentAction).
204#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
205#[serde(rename_all = "camelCase")]
206pub struct CFRecentAction {
207    pub time_seconds: i64,
208    pub blog_entry: Option<CFBlogEntry>,
209    pub comment: Option<CFComment>,
210}
211
212#[cfg(feature = "serde_yaml")]
213impl fmt::Display for CFRecentAction {
214    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
215    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216        match serde_yaml::to_string(self) {
217            Ok(s) => write!(f, "{}", s),
218            Err(_) => Err(fmt::Error),
219        }
220    }
221}
222
223/// Struct representing a Codeforces
224/// [rating change](https://codeforces.com/apiHelp/objects#RatingChange).
225#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
226#[serde(rename_all = "camelCase")]
227pub struct CFRatingChange {
228    pub contest_id: i64,
229    pub contest_name: String,
230    pub handle: String,
231    pub rank: i64,
232    pub rating_update_time_seconds: i64,
233    pub old_rating: i64,
234    pub new_rating: i64,
235}
236
237#[cfg(feature = "serde_yaml")]
238impl fmt::Display for CFRatingChange {
239    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
240    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241        match serde_yaml::to_string(self) {
242            Ok(s) => write!(f, "{}", s),
243            Err(_) => Err(fmt::Error),
244        }
245    }
246}
247
248/// Contest type returned by Codeforces API (eg. IOI, ICPC).
249#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
250pub enum CFContestType {
251    #[serde(rename = "CF")]
252    Codeforces,
253    IOI,
254    ICPC,
255}
256
257#[cfg(feature = "serde_yaml")]
258impl fmt::Display for CFContestType {
259    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
260    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
261        match serde_yaml::to_string(self) {
262            Ok(s) => write!(f, "{}", s),
263            Err(_) => Err(fmt::Error),
264        }
265    }
266}
267
268/// Contest phase returned by Codeforces API (eg. PendingSystemTest).
269#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
270#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
271pub enum CFContestPhase {
272    Before,
273    Coding,
274    PendingSystemTest,
275    SystemTest,
276    Finished,
277}
278
279#[cfg(feature = "serde_yaml")]
280impl fmt::Display for CFContestPhase {
281    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
282    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
283        match serde_yaml::to_string(self) {
284            Ok(s) => write!(f, "{}", s),
285            Err(_) => Err(fmt::Error),
286        }
287    }
288}
289
290/// Struct representing the object returned by a
291/// [`contest.standings`](super::requests::CFContestCommand::Standings)
292/// request.
293#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
294#[serde(rename_all = "camelCase")]
295pub struct CFContestStandings {
296    pub contest: CFContest,
297    pub problems: Vec<CFProblem>,
298    pub rows: Vec<CFRanklistRow>,
299}
300
301#[cfg(feature = "serde_yaml")]
302impl fmt::Display for CFContestStandings {
303    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
304    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305        match serde_yaml::to_string(self) {
306            Ok(s) => write!(f, "{}", s),
307            Err(_) => Err(fmt::Error),
308        }
309    }
310}
311
312/// Struct representing a Codeforces
313/// [contest](https://codeforces.com/apiHelp/objects#Contest).
314#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
315#[serde(rename_all = "camelCase")]
316pub struct CFContest {
317    pub id: i64,
318    pub name: String,
319    #[serde(rename = "type")]
320    pub contest_type: CFContestType,
321    pub phase: CFContestPhase,
322    pub duration_seconds: i64,
323    pub start_time_seconds: Option<i64>,
324    pub relative_time_seconds: Option<i64>,
325    pub prepared_by: Option<String>,
326    pub website_url: Option<String>,
327    pub description: Option<String>,
328    pub difficulty: Option<i64>,
329    pub kind: Option<String>,
330    pub icpc_region: Option<String>,
331    pub country: Option<String>,
332    pub city: Option<String>,
333    pub season: Option<String>,
334}
335
336#[cfg(feature = "serde_yaml")]
337impl fmt::Display for CFContest {
338    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
339    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340        match serde_yaml::to_string(self) {
341            Ok(s) => write!(f, "{}", s),
342            Err(_) => Err(fmt::Error),
343        }
344    }
345}
346
347/// Participant type returned by Codeforces API (eg. Contestant, Virtual).
348#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
349#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
350pub enum CFParticipantType {
351    Contestant,
352    Practice,
353    Virtual,
354    Manager,
355    OutOfCompetition,
356}
357
358#[cfg(feature = "serde_yaml")]
359impl fmt::Display for CFParticipantType {
360    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
361    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
362        match serde_yaml::to_string(self) {
363            Ok(s) => write!(f, "{}", s),
364            Err(_) => Err(fmt::Error),
365        }
366    }
367}
368
369/// Struct representing a Codeforces
370/// [party](https://codeforces.com/apiHelp/objects#Party).
371#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
372#[serde(rename_all = "camelCase")]
373pub struct CFParty {
374    pub contest_id: Option<i64>,
375    pub members: Vec<CFMember>,
376    pub participant_type: CFParticipantType,
377    pub team_id: Option<i64>,
378    pub team_name: Option<String>,
379    pub ghost: bool,
380    pub room: Option<i64>,
381    pub start_time_seconds: Option<i64>,
382}
383
384#[cfg(feature = "serde_yaml")]
385impl fmt::Display for CFParty {
386    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
387    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
388        match serde_yaml::to_string(self) {
389            Ok(s) => write!(f, "{}", s),
390            Err(_) => Err(fmt::Error),
391        }
392    }
393}
394
395/// Struct representing a Codeforces
396/// [member](https://codeforces.com/apiHelp/objects#Member).
397#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
398#[serde(rename_all = "camelCase")]
399pub struct CFMember {
400    pub handle: String,
401}
402
403#[cfg(feature = "serde_yaml")]
404impl fmt::Display for CFMember {
405    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
406    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
407        match serde_yaml::to_string(self) {
408            Ok(s) => write!(f, "{}", s),
409            Err(_) => Err(fmt::Error),
410        }
411    }
412}
413
414/// Problem type returned by Codeforces API (Programming, Question).
415#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
416#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
417pub enum CFProblemType {
418    Programming,
419    Question,
420}
421
422#[cfg(feature = "serde_yaml")]
423impl fmt::Display for CFProblemType {
424    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
425    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426        match serde_yaml::to_string(self) {
427            Ok(s) => write!(f, "{}", s),
428            Err(_) => Err(fmt::Error),
429        }
430    }
431}
432
433/// Struct representing a Codeforces
434/// [problem](https://codeforces.com/apiHelp/objects#Problem).
435#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
436#[serde(rename_all = "camelCase")]
437pub struct CFProblem {
438    pub contest_id: Option<i64>,
439    pub problemset_name: Option<String>,
440    pub index: Option<String>,
441    pub name: String,
442    #[serde(rename = "type")]
443    pub problem_type: CFProblemType,
444    pub points: Option<f64>,
445    pub rating: Option<i64>,
446    pub tags: Vec<String>,
447    #[serde(skip_deserializing)]
448    pub input_testcases: Option<Vec<String>>,
449}
450
451#[cfg(feature = "serde_yaml")]
452impl fmt::Display for CFProblem {
453    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
454    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
455        match serde_yaml::to_string(self) {
456            Ok(s) => write!(f, "{}", s),
457            Err(_) => Err(fmt::Error),
458        }
459    }
460}
461
462/// Struct representing a Codeforces problem
463/// [statistics](https://codeforces.com/apiHelp/objects#ProblemStatistics).
464#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
465#[serde(rename_all = "camelCase")]
466pub struct CFProblemStatistics {
467    pub contest_id: Option<i64>,
468    pub index: Option<String>,
469    pub solved_count: i64,
470}
471
472#[cfg(feature = "serde_yaml")]
473impl fmt::Display for CFProblemStatistics {
474    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
475    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
476        match serde_yaml::to_string(self) {
477            Ok(s) => write!(f, "{}", s),
478            Err(_) => Err(fmt::Error),
479        }
480    }
481}
482
483/// Struct representing the object returned by a
484/// [`problemset.problems`](super::requests::CFProblemsetCommand::Problems)
485/// request.
486#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
487#[serde(rename_all = "camelCase")]
488pub struct CFProblemset {
489    pub problems: Vec<CFProblem>,
490    pub problem_statistics: Vec<CFProblemStatistics>,
491}
492
493#[cfg(feature = "serde_yaml")]
494impl fmt::Display for CFProblemset {
495    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
496    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
497        match serde_yaml::to_string(self) {
498            Ok(s) => write!(f, "{}", s),
499            Err(_) => Err(fmt::Error),
500        }
501    }
502}
503
504/// Submission verdict returned by Codeforces API (eg. Ok, CompilationError).
505#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
506#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
507pub enum CFSubmissionVerdict {
508    Failed,
509    Ok,
510    Partial,
511    CompilationError,
512    RuntimeError,
513    WrongAnswer,
514    PresentationError,
515    TimeLimitExceeded,
516    MemoryLimitExceeded,
517    IdlenessLimitExceeded,
518    SecurityViolated,
519    Crashed,
520    InputPreparationCrashed,
521    Challenged,
522    Skipped,
523    Testing,
524    Rejected,
525}
526
527#[cfg(feature = "serde_yaml")]
528impl fmt::Display for CFSubmissionVerdict {
529    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
530    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
531        match serde_yaml::to_string(self) {
532            Ok(s) => write!(f, "{}", s),
533            Err(_) => Err(fmt::Error),
534        }
535    }
536}
537
538/// Testset returned by Codeforces API (eg. Pretests, TestSet1).
539#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
540#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
541pub enum CFTestset {
542    Samples,
543    Pretests,
544    Tests,
545    Challenges,
546    #[serde(rename = "TESTS1")]
547    TestSet1,
548    #[serde(rename = "TESTS2")]
549    TestSet2,
550    #[serde(rename = "TESTS3")]
551    TestSet3,
552    #[serde(rename = "TESTS4")]
553    TestSet4,
554    #[serde(rename = "TESTS5")]
555    TestSet5,
556    #[serde(rename = "TESTS6")]
557    TestSet6,
558    #[serde(rename = "TESTS7")]
559    TestSet7,
560    #[serde(rename = "TESTS8")]
561    TestSet8,
562    #[serde(rename = "TESTS9")]
563    TestSet9,
564    #[serde(rename = "TESTS10")]
565    TestSet10,
566}
567
568#[cfg(feature = "serde_yaml")]
569impl fmt::Display for CFTestset {
570    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
571    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
572        match serde_yaml::to_string(self) {
573            Ok(s) => write!(f, "{}", s),
574            Err(_) => Err(fmt::Error),
575        }
576    }
577}
578
579/// Struct representing a Codeforces
580/// [submission](https://codeforces.com/apiHelp/objects#Submission).
581#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
582#[serde(rename_all = "camelCase")]
583pub struct CFSubmission {
584    pub id: i64,
585    pub contest_id: Option<i64>,
586    pub creation_time_seconds: i64,
587    pub relative_time_seconds: Option<i64>,
588    pub problem: CFProblem,
589    pub author: CFParty,
590    pub programming_language: String,
591    pub verdict: Option<CFSubmissionVerdict>,
592    pub testset: CFTestset,
593    pub passed_test_count: i64,
594    pub time_consumed_millis: i64,
595    pub memory_consumed_bytes: i64,
596    pub points: Option<f64>,
597}
598
599#[cfg(feature = "serde_yaml")]
600impl fmt::Display for CFSubmission {
601    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
602    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
603        match serde_yaml::to_string(self) {
604            Ok(s) => write!(f, "{}", s),
605            Err(_) => Err(fmt::Error),
606        }
607    }
608}
609
610/// Hack verdict returned by Codeforces API (eg. HackSuccessful, Testing).
611#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
612#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
613pub enum CFHackVerdict {
614    HackSuccessful,
615    HackUnsuccessful,
616    InvalidInput,
617    GeneratorIncompilable,
618    GeneratorCrashed,
619    Ignored,
620    Testing,
621    Other,
622}
623
624#[cfg(feature = "serde_yaml")]
625impl fmt::Display for CFHackVerdict {
626    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
627    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
628        match serde_yaml::to_string(self) {
629            Ok(s) => write!(f, "{}", s),
630            Err(_) => Err(fmt::Error),
631        }
632    }
633}
634
635/// Struct representing a Codeforces judge protocol for hacks.
636#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
637#[serde(rename_all = "camelCase")]
638pub struct CFJudgeProtocol {
639    pub manual: String,
640    pub protocol: String,
641    pub verdict: String,
642}
643
644#[cfg(feature = "serde_yaml")]
645impl fmt::Display for CFJudgeProtocol {
646    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
647    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
648        match serde_yaml::to_string(self) {
649            Ok(s) => write!(f, "{}", s),
650            Err(_) => Err(fmt::Error),
651        }
652    }
653}
654
655/// Struct representing a Codeforces
656/// [hack](https://codeforces.com/apiHelp/objects#Hack).
657#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
658#[serde(rename_all = "camelCase")]
659pub struct CFHack {
660    pub id: i64,
661    pub creation_time_seconds: i64,
662    pub hacker: CFParty,
663    pub defender: CFParty,
664    pub verdict: Option<CFHackVerdict>,
665    pub problem: CFProblem,
666    pub test: Option<String>,
667    pub judge_protocol: Option<CFJudgeProtocol>,
668}
669
670#[cfg(feature = "serde_yaml")]
671impl fmt::Display for CFHack {
672    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
673    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
674        match serde_yaml::to_string(self) {
675            Ok(s) => write!(f, "{}", s),
676            Err(_) => Err(fmt::Error),
677        }
678    }
679}
680
681/// Struct representing a Codeforces
682/// [ranklist row](https://codeforces.com/apiHelp/objects#RanklistRow).
683#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
684#[serde(rename_all = "camelCase")]
685pub struct CFRanklistRow {
686    pub party: CFParty,
687    pub rank: i64,
688    pub points: f64,
689    pub penalty: i64,
690    pub successful_hack_count: i64,
691    pub unsuccessful_hack_count: i64,
692    pub problem_results: Vec<CFProblemResult>,
693    pub last_submission_time_seconds: Option<i64>,
694}
695
696#[cfg(feature = "serde_yaml")]
697impl fmt::Display for CFRanklistRow {
698    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
699    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
700        match serde_yaml::to_string(self) {
701            Ok(s) => write!(f, "{}", s),
702            Err(_) => Err(fmt::Error),
703        }
704    }
705}
706
707/// Problem result type returned by Codeforces API (Preliminary, Final).
708#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
709#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
710pub enum CFProblemResultType {
711    Preliminary,
712    Final,
713}
714
715#[cfg(feature = "serde_yaml")]
716impl fmt::Display for CFProblemResultType {
717    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
718    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719        match serde_yaml::to_string(self) {
720            Ok(s) => write!(f, "{}", s),
721            Err(_) => Err(fmt::Error),
722        }
723    }
724}
725
726/// Struct representing a Codeforces
727/// [problem result](https://codeforces.com/apiHelp/objects#ProblemResult).
728#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
729#[serde(rename_all = "camelCase")]
730pub struct CFProblemResult {
731    pub points: f64,
732    pub penalty: Option<i64>,
733    pub rejected_attempt_count: i64,
734    #[serde(rename = "type")]
735    pub problem_result_type: CFProblemResultType,
736    pub best_submission_time_seconds: Option<i64>,
737}
738
739#[cfg(feature = "serde_yaml")]
740impl fmt::Display for CFProblemResult {
741    /// Display type as yaml using `serde_yaml` (requires `serde_yaml` feature).
742    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
743        match serde_yaml::to_string(self) {
744            Ok(s) => write!(f, "{}", s),
745            Err(_) => Err(fmt::Error),
746        }
747    }
748}