cp_cli_platform_codeforces/
lib.rs1mod client;
4mod error;
5
6pub use client::Client;
7pub use error::Error;
8
9#[derive(Clone)]
11pub struct ApiCredentials {
12 key: Box<str>,
13 secret: Box<str>,
14}
15
16impl ApiCredentials {
17 pub fn new(key: impl Into<Box<str>>, secret: impl Into<Box<str>>) -> Result<Self, Error> {
18 let key = key.into();
19 let secret = secret.into();
20 if !valid_api_credential(&key) {
21 return Err(Error::InvalidApiKey);
22 }
23 if !valid_api_credential(&secret) {
24 return Err(Error::InvalidApiSecret);
25 }
26 Ok(Self { key, secret })
27 }
28}
29
30fn valid_api_credential(value: &str) -> bool {
31 !value.is_empty()
32 && value.len() <= 128
33 && value
34 .bytes()
35 .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'-'))
36}
37
38#[derive(Debug, PartialEq, Eq)]
39pub struct Problem {
40 pub contest_id: u32,
41 pub index: Box<str>,
42 pub title: Box<str>,
43 pub rating: Option<u16>,
44 pub tags: Vec<Box<str>>,
45 pub solved_count: Option<u32>,
46 pub url: Box<str>,
47 pub statement: Option<Box<str>>,
49}
50
51#[derive(Debug, PartialEq, Eq)]
53pub struct Contest {
54 pub id: u32,
55 pub name: Box<str>,
56 pub kind: Box<str>,
57 pub phase: Box<str>,
58 pub start_time_seconds: Option<i64>,
59 pub duration_seconds: Option<u32>,
60}
61
62#[derive(Debug, PartialEq, Eq)]
64pub struct UserProfile {
65 pub handle: Box<str>,
66 pub first_name: Option<Box<str>>,
67 pub last_name: Option<Box<str>>,
68 pub country: Option<Box<str>>,
69 pub city: Option<Box<str>>,
70 pub organization: Option<Box<str>>,
71 pub rank: Option<Box<str>>,
72 pub rating: Option<i32>,
73 pub max_rank: Option<Box<str>>,
74 pub max_rating: Option<i32>,
75 pub contribution: i32,
76 pub friend_of_count: u32,
77 pub registration_time_seconds: i64,
78 pub last_online_time_seconds: i64,
79}
80
81#[derive(Debug, PartialEq, Eq)]
83pub struct RatingChange {
84 pub contest_id: u32,
85 pub contest_name: Box<str>,
86 pub rank: u32,
87 pub old_rating: i32,
88 pub new_rating: i32,
89 pub rating_update_time_seconds: i64,
90}
91
92#[derive(Debug, PartialEq, Eq)]
94pub struct Submission {
95 pub id: u64,
96 pub contest_id: Option<u32>,
97 pub creation_time_seconds: i64,
98 pub relative_time_seconds: i64,
99 pub problem_index: Box<str>,
100 pub problem_name: Box<str>,
101 pub programming_language: Box<str>,
102 pub verdict: Option<Box<str>>,
103 pub testset: Box<str>,
104 pub passed_test_count: u32,
105 pub time_consumed_millis: u32,
106 pub memory_consumed_bytes: u64,
107}
108
109#[derive(Debug, PartialEq, Eq)]
111pub struct DiscussionPreview {
112 pub id: u32,
113 pub author: Box<str>,
114 pub title: Box<str>,
115 pub created_time_seconds: i64,
116 pub activity_time_seconds: i64,
117 pub rating: i32,
118 pub tags: Vec<Box<str>>,
119 pub latest_comment: Option<DiscussionComment>,
120 pub url: Box<str>,
121}
122
123#[derive(Debug, PartialEq, Eq)]
125pub struct Discussion {
126 pub id: u32,
127 pub author: Box<str>,
128 pub title: Box<str>,
129 pub content_html: Box<str>,
130 pub created_time_seconds: i64,
131 pub modified_time_seconds: Option<i64>,
132 pub rating: i32,
133 pub tags: Vec<Box<str>>,
134 pub comments: Vec<DiscussionComment>,
135 pub url: Box<str>,
136}
137
138#[derive(Debug, PartialEq, Eq)]
140pub struct DiscussionComment {
141 pub id: u32,
142 pub author: Box<str>,
143 pub content_html: Box<str>,
144 pub created_time_seconds: i64,
145 pub parent_comment_id: Option<u32>,
146 pub rating: i32,
147}
148
149#[cfg(test)]
150mod tests;