1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Deserialize)]
5pub struct Issue {
6 pub id: String,
7 pub key: String,
8 #[serde(rename = "self")]
9 pub self_url: String,
10 pub fields: IssueFields,
11}
12
13#[derive(Debug, Clone, Deserialize)]
15pub struct IssueFields {
16 pub summary: String,
17 pub description: Option<serde_json::Value>,
18 pub status: Status,
19 pub priority: Option<Priority>,
20 pub issuetype: IssueType,
21 pub project: Project,
22 pub assignee: Option<User>,
23 pub reporter: Option<User>,
24 pub labels: Vec<String>,
25 pub created: String,
26 pub updated: String,
27 pub resolutiondate: Option<String>,
28}
29
30#[derive(Debug, Clone, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct Status {
34 pub id: String,
35 pub name: String,
36 pub status_category: StatusCategory,
37}
38
39#[derive(Debug, Clone, Deserialize)]
41pub struct StatusCategory {
42 pub id: u32,
43 pub key: String,
44 pub name: String,
45}
46
47#[derive(Debug, Clone, Deserialize)]
49pub struct Priority {
50 pub id: String,
51 pub name: String,
52}
53
54#[derive(Debug, Clone, Deserialize)]
56pub struct IssueType {
57 pub id: String,
58 pub name: String,
59 pub subtask: bool,
60}
61
62#[derive(Debug, Clone, Deserialize)]
64pub struct Project {
65 pub id: String,
66 pub key: String,
67 pub name: String,
68 #[serde(rename = "self")]
69 pub self_url: String,
70}
71
72#[derive(Debug, Clone, Deserialize)]
74#[serde(rename_all = "camelCase")]
75pub struct User {
76 pub account_id: String,
77 pub display_name: String,
78 pub email_address: Option<String>,
79 pub avatar_urls: Option<AvatarUrls>,
80 pub active: bool,
81}
82
83#[derive(Debug, Clone, Deserialize)]
85pub struct AvatarUrls {
86 #[serde(rename = "48x48")]
87 pub large: Option<String>,
88 #[serde(rename = "24x24")]
89 pub small: Option<String>,
90 #[serde(rename = "16x16")]
91 pub xsmall: Option<String>,
92 #[serde(rename = "32x32")]
93 pub medium: Option<String>,
94}
95
96#[derive(Debug, Clone, Deserialize)]
98#[serde(rename_all = "camelCase")]
99pub struct Sprint {
100 pub id: u64,
101 pub name: String,
102 pub state: String,
103 pub start_date: Option<String>,
104 pub end_date: Option<String>,
105 pub complete_date: Option<String>,
106 pub origin_board_id: u64,
107}
108
109#[derive(Debug, Clone, Deserialize)]
111pub struct Board {
112 pub id: u64,
113 pub name: String,
114 #[serde(rename = "type")]
115 pub board_type: String,
116}
117
118#[derive(Debug, Clone, Deserialize)]
120pub struct Comment {
121 pub id: String,
122 pub author: User,
123 pub body: serde_json::Value,
124 pub created: String,
125 pub updated: String,
126}
127
128#[derive(Debug, Clone, Deserialize)]
130pub struct Transition {
131 pub id: String,
132 pub name: String,
133 pub to: Status,
134}
135
136#[derive(Debug, Clone, Deserialize)]
138#[serde(rename_all = "camelCase")]
139pub struct SearchResult {
140 pub start_at: u32,
141 pub max_results: u32,
142 pub total: u32,
143 pub issues: Vec<Issue>,
144}
145
146#[derive(Debug, Clone, Serialize)]
148pub struct CreateIssueInput {
149 pub fields: CreateIssueFields,
150}
151
152#[derive(Debug, Clone, Default, Serialize)]
153pub struct CreateIssueFields {
154 pub project: ProjectRef,
155 pub summary: String,
156 pub issuetype: IssueTypeRef,
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub description: Option<serde_json::Value>,
159 #[serde(skip_serializing_if = "Option::is_none")]
160 pub priority: Option<PriorityRef>,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub assignee: Option<UserRef>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub labels: Option<Vec<String>>,
165}
166
167#[derive(Debug, Clone, Default, Serialize)]
168pub struct ProjectRef {
169 pub key: String,
170}
171
172#[derive(Debug, Clone, Default, Serialize)]
173pub struct IssueTypeRef {
174 pub name: String,
175}
176
177#[derive(Debug, Clone, Serialize)]
178pub struct PriorityRef {
179 pub name: String,
180}
181
182#[derive(Debug, Clone, Serialize)]
183#[serde(rename_all = "camelCase")]
184pub struct UserRef {
185 pub account_id: String,
186}
187
188impl CreateIssueInput {
189 pub fn new(project_key: impl Into<String>, summary: impl Into<String>, issue_type: impl Into<String>) -> Self {
190 Self {
191 fields: CreateIssueFields {
192 project: ProjectRef { key: project_key.into() },
193 summary: summary.into(),
194 issuetype: IssueTypeRef { name: issue_type.into() },
195 ..Default::default()
196 },
197 }
198 }
199
200 pub fn description(mut self, desc: serde_json::Value) -> Self {
201 self.fields.description = Some(desc);
202 self
203 }
204
205 pub fn priority(mut self, priority: impl Into<String>) -> Self {
206 self.fields.priority = Some(PriorityRef { name: priority.into() });
207 self
208 }
209
210 pub fn assignee(mut self, account_id: impl Into<String>) -> Self {
211 self.fields.assignee = Some(UserRef { account_id: account_id.into() });
212 self
213 }
214
215 pub fn labels(mut self, labels: Vec<String>) -> Self {
216 self.fields.labels = Some(labels);
217 self
218 }
219}
220
221#[derive(Debug, Clone, Default, Serialize)]
223pub struct UpdateIssueInput {
224 pub fields: UpdateIssueFields,
225}
226
227#[derive(Debug, Clone, Default, Serialize)]
228pub struct UpdateIssueFields {
229 #[serde(skip_serializing_if = "Option::is_none")]
230 pub summary: Option<String>,
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub description: Option<serde_json::Value>,
233 #[serde(skip_serializing_if = "Option::is_none")]
234 pub priority: Option<PriorityRef>,
235 #[serde(skip_serializing_if = "Option::is_none")]
236 pub assignee: Option<UserRef>,
237 #[serde(skip_serializing_if = "Option::is_none")]
238 pub labels: Option<Vec<String>>,
239}
240
241impl UpdateIssueInput {
242 pub fn new() -> Self {
243 Self::default()
244 }
245
246 pub fn summary(mut self, summary: impl Into<String>) -> Self {
247 self.fields.summary = Some(summary.into());
248 self
249 }
250
251 pub fn description(mut self, desc: serde_json::Value) -> Self {
252 self.fields.description = Some(desc);
253 self
254 }
255
256 pub fn priority(mut self, priority: impl Into<String>) -> Self {
257 self.fields.priority = Some(PriorityRef { name: priority.into() });
258 self
259 }
260
261 pub fn assignee(mut self, account_id: impl Into<String>) -> Self {
262 self.fields.assignee = Some(UserRef { account_id: account_id.into() });
263 self
264 }
265}
266
267#[derive(Debug, Clone, Serialize)]
269pub struct AddCommentInput {
270 pub body: serde_json::Value,
271}
272
273impl AddCommentInput {
274 pub fn text(text: impl Into<String>) -> Self {
275 Self {
276 body: serde_json::json!({
277 "type": "doc",
278 "version": 1,
279 "content": [{
280 "type": "paragraph",
281 "content": [{
282 "type": "text",
283 "text": text.into()
284 }]
285 }]
286 }),
287 }
288 }
289}
290
291#[derive(Debug, Clone, Serialize)]
293pub struct TransitionInput {
294 pub transition: TransitionRef,
295}
296
297#[derive(Debug, Clone, Serialize)]
298pub struct TransitionRef {
299 pub id: String,
300}
301
302impl TransitionInput {
303 pub fn new(transition_id: impl Into<String>) -> Self {
304 Self {
305 transition: TransitionRef {
306 id: transition_id.into(),
307 },
308 }
309 }
310}
311
312#[derive(Debug, Clone, Deserialize)]
314pub struct CreatedIssue {
315 pub id: String,
316 pub key: String,
317 #[serde(rename = "self")]
318 pub self_url: String,
319}