1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ClickUpUser {
14 pub id: u64,
15 pub username: String,
16 #[serde(default)]
17 pub email: Option<String>,
18 #[serde(default, rename = "profilePicture")]
19 pub profile_picture: Option<String>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct ClickUpTask {
28 pub id: String,
29 #[serde(default)]
30 pub custom_id: Option<String>,
31 pub name: String,
32 #[serde(default)]
33 pub description: Option<String>,
34 #[serde(default)]
35 pub text_content: Option<String>,
36 pub status: ClickUpStatus,
37 #[serde(default)]
38 pub priority: Option<ClickUpPriority>,
39 #[serde(default)]
40 pub tags: Vec<ClickUpTag>,
41 #[serde(default)]
42 pub assignees: Vec<ClickUpUser>,
43 #[serde(default)]
44 pub creator: Option<ClickUpUser>,
45 pub url: String,
46 #[serde(default)]
47 pub date_created: Option<String>,
48 #[serde(default)]
49 pub date_updated: Option<String>,
50 #[serde(default)]
51 pub parent: Option<String>,
52 #[serde(default)]
53 pub subtasks: Option<Vec<ClickUpTask>>,
54 #[serde(default)]
57 pub dependencies: Option<Vec<serde_json::Value>>,
58 #[serde(default)]
60 pub linked_tasks: Option<Vec<ClickUpLinkedTask>>,
61 #[serde(default)]
66 pub attachments: Vec<ClickUpAttachment>,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct ClickUpAttachment {
72 pub id: String,
73 #[serde(default)]
74 pub title: Option<String>,
75 #[serde(default)]
77 pub url: Option<String>,
78 #[serde(default)]
80 pub size: Option<serde_json::Value>,
81 #[serde(default)]
83 pub extension: Option<String>,
84 #[serde(default)]
85 pub mimetype: Option<String>,
86 #[serde(default)]
88 pub date: Option<String>,
89 #[serde(default)]
91 pub user: Option<ClickUpUser>,
92}
93
94#[derive(Debug, Clone, Serialize, Deserialize)]
96pub struct ClickUpStatus {
97 pub status: String,
98 #[serde(default, rename = "type")]
99 pub status_type: Option<String>,
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct ClickUpPriority {
105 pub id: String,
106 pub priority: String,
107 #[serde(default)]
108 pub color: Option<String>,
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct ClickUpTag {
113 pub name: String,
114}
115
116#[derive(Debug, Clone, Serialize, Deserialize)]
118pub struct ClickUpLinkedTask {
119 pub task_id: String,
120 pub link_id: String,
121 #[serde(default)]
123 pub link_type: Option<String>,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct ClickUpTaskList {
133 pub tasks: Vec<ClickUpTask>,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize)]
141pub struct ClickUpComment {
142 pub id: String,
143 pub comment_text: String,
144 #[serde(default)]
145 pub user: Option<ClickUpUser>,
146 #[serde(default)]
147 pub date: Option<String>,
148}
149
150#[derive(Debug, Clone, Serialize, Deserialize)]
152pub struct ClickUpCommentList {
153 pub comments: Vec<ClickUpComment>,
154}
155
156#[derive(Debug, Clone, Deserialize)]
162pub struct ClickUpListStatus {
163 pub status: String,
164 #[serde(default, rename = "type")]
165 pub status_type: Option<String>,
166 #[serde(default)]
167 pub color: Option<String>,
168 #[serde(default)]
169 pub orderindex: Option<u32>,
170}
171
172#[derive(Debug, Clone, Deserialize)]
174pub struct ClickUpListInfo {
175 pub statuses: Vec<ClickUpListStatus>,
176}
177
178#[derive(Debug, Clone, Deserialize)]
180pub struct ClickUpDependencyResponse {
181 #[serde(default)]
182 pub dependency: Option<serde_json::Value>,
183}
184
185#[derive(Debug, Clone, Deserialize)]
187pub struct ClickUpLinkResponse {
188 #[serde(default)]
189 pub link: Option<serde_json::Value>,
190}
191
192#[derive(Debug, Clone, Serialize)]
197pub struct CreateTaskRequest {
198 pub name: String,
199 #[serde(skip_serializing_if = "Option::is_none")]
200 pub description: Option<String>,
201 #[serde(skip_serializing_if = "Option::is_none")]
202 pub markdown_content: Option<String>,
203 #[serde(skip_serializing_if = "Option::is_none")]
204 pub parent: Option<String>,
205 #[serde(skip_serializing_if = "Option::is_none")]
206 pub status: Option<String>,
207 #[serde(skip_serializing_if = "Option::is_none")]
208 pub priority: Option<u8>,
209 #[serde(skip_serializing_if = "Option::is_none")]
210 pub tags: Option<Vec<String>>,
211 #[serde(skip_serializing_if = "Option::is_none")]
212 pub assignees: Option<Vec<u64>>,
213}
214
215#[derive(Debug, Clone, Serialize, Default)]
216pub struct UpdateTaskRequest {
217 #[serde(skip_serializing_if = "Option::is_none")]
218 pub name: Option<String>,
219 #[serde(skip_serializing_if = "Option::is_none")]
220 pub description: Option<String>,
221 #[serde(skip_serializing_if = "Option::is_none")]
222 pub markdown_content: Option<String>,
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub status: Option<String>,
225 #[serde(skip_serializing_if = "Option::is_none")]
226 pub priority: Option<u8>,
227 #[serde(skip_serializing_if = "Option::is_none")]
228 pub parent: Option<String>,
229 #[serde(skip_serializing_if = "Option::is_none")]
230 pub tags: Option<Vec<String>>,
231}
232
233#[derive(Debug, Clone, Serialize)]
234pub struct CreateCommentRequest {
235 pub comment_text: String,
236}
237
238#[derive(Debug, Clone, Deserialize)]
241pub struct CreateCommentResponse {
242 #[serde(deserialize_with = "value_to_string")]
243 pub id: String,
244 #[serde(default, deserialize_with = "option_value_to_string")]
245 pub date: Option<String>,
246}
247
248fn value_to_string<'de, D>(deserializer: D) -> std::result::Result<String, D::Error>
250where
251 D: serde::Deserializer<'de>,
252{
253 let value = serde_json::Value::deserialize(deserializer)?;
254 match value {
255 serde_json::Value::String(s) => Ok(s),
256 serde_json::Value::Number(n) => Ok(n.to_string()),
257 other => Ok(other.to_string()),
258 }
259}
260
261fn option_value_to_string<'de, D>(deserializer: D) -> std::result::Result<Option<String>, D::Error>
263where
264 D: serde::Deserializer<'de>,
265{
266 let value = Option::<serde_json::Value>::deserialize(deserializer)?;
267 Ok(value.map(|v| match v {
268 serde_json::Value::String(s) => s,
269 serde_json::Value::Number(n) => n.to_string(),
270 other => other.to_string(),
271 }))
272}