1use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Clone, Deserialize)]
13pub struct JiraUser {
14 #[serde(default, rename = "accountId")]
16 pub account_id: Option<String>,
17 #[serde(default)]
19 pub name: Option<String>,
20 #[serde(default, rename = "displayName")]
21 pub display_name: Option<String>,
22 #[serde(default, rename = "emailAddress")]
23 pub email_address: Option<String>,
24}
25
26#[derive(Debug, Clone, Deserialize)]
31pub struct JiraIssue {
32 pub id: String,
33 pub key: String,
35 pub fields: JiraIssueFields,
36}
37
38#[derive(Debug, Clone, Deserialize)]
39pub struct JiraIssueFields {
40 #[serde(default)]
41 pub summary: Option<String>,
42 #[serde(default)]
44 pub description: Option<serde_json::Value>,
45 #[serde(default)]
46 pub status: Option<JiraStatus>,
47 #[serde(default)]
48 pub priority: Option<JiraPriority>,
49 #[serde(default)]
50 pub assignee: Option<JiraUser>,
51 #[serde(default)]
53 pub reporter: Option<JiraUser>,
54 #[serde(default)]
55 pub labels: Vec<String>,
56 #[serde(default)]
58 pub created: Option<String>,
59 #[serde(default)]
61 pub updated: Option<String>,
62 #[serde(default)]
64 pub parent: Option<Box<JiraIssue>>,
65 #[serde(default)]
67 pub subtasks: Vec<JiraIssue>,
68 #[serde(default)]
69 pub issuelinks: Vec<JiraIssueLink>,
70 #[serde(default)]
73 pub attachment: Vec<JiraAttachment>,
74}
75
76#[derive(Debug, Clone, Deserialize)]
78pub struct JiraAttachment {
79 pub id: String,
81 #[serde(default)]
82 pub filename: Option<String>,
83 #[serde(default)]
85 pub content: Option<String>,
86 #[serde(default)]
87 pub size: Option<u64>,
88 #[serde(default, rename = "mimeType")]
89 pub mime_type: Option<String>,
90 #[serde(default)]
92 pub created: Option<String>,
93 #[serde(default)]
95 pub author: Option<JiraUser>,
96}
97
98#[derive(Debug, Clone, Deserialize)]
99#[serde(rename_all = "camelCase")]
100pub struct JiraStatus {
101 pub name: String,
102 #[serde(default)]
104 pub status_category: Option<JiraStatusCategory>,
105}
106
107#[derive(Debug, Clone, Deserialize)]
108pub struct JiraStatusCategory {
109 pub key: String,
111}
112
113#[derive(Debug, Clone, Deserialize)]
114pub struct JiraPriority {
115 pub name: String,
116}
117
118#[derive(Debug, Clone, Deserialize)]
123pub struct JiraIssueLink {
124 #[serde(default)]
126 pub id: Option<String>,
127 #[serde(rename = "type")]
128 pub link_type: JiraIssueLinkType,
129 #[serde(default, rename = "inwardIssue")]
131 pub inward_issue: Option<Box<JiraIssue>>,
132 #[serde(default, rename = "outwardIssue")]
134 pub outward_issue: Option<Box<JiraIssue>>,
135}
136
137#[derive(Debug, Clone, Deserialize)]
138pub struct JiraIssueLinkType {
139 pub name: String,
141 #[serde(default)]
143 pub inward: Option<String>,
144 #[serde(default)]
146 pub outward: Option<String>,
147}
148
149#[derive(Debug, Clone, Deserialize)]
155pub struct JiraSearchResponse {
156 pub issues: Vec<JiraIssue>,
157 #[serde(default, rename = "startAt")]
159 pub start_at: Option<u32>,
160 #[serde(default, rename = "maxResults")]
162 pub max_results: Option<u32>,
163 #[serde(default)]
165 pub total: Option<u32>,
166}
167
168#[derive(Debug, Clone, Deserialize)]
170pub struct JiraCloudSearchResponse {
171 pub issues: Vec<JiraIssue>,
172 #[serde(default, rename = "nextPageToken")]
173 pub next_page_token: Option<String>,
174}
175
176#[derive(Debug, Clone, Deserialize)]
182pub struct JiraComment {
183 pub id: String,
185 #[serde(default)]
187 pub body: Option<serde_json::Value>,
188 #[serde(default)]
190 pub author: Option<JiraUser>,
191 #[serde(default)]
193 pub created: Option<String>,
194 #[serde(default)]
196 pub updated: Option<String>,
197}
198
199#[derive(Debug, Clone, Deserialize)]
201pub struct JiraCommentsResponse {
202 pub comments: Vec<JiraComment>,
203}
204
205#[derive(Debug, Clone, Deserialize)]
211pub struct JiraTransition {
212 pub id: String,
214 pub name: String,
216 pub to: JiraStatus,
218}
219
220#[derive(Debug, Clone, Deserialize)]
222pub struct JiraTransitionsResponse {
223 pub transitions: Vec<JiraTransition>,
225}
226
227#[derive(Debug, Clone, Serialize)]
233pub struct CreateIssuePayload {
234 pub fields: CreateIssueFields,
236}
237
238#[derive(Debug, Clone, Serialize)]
240pub struct CreateIssueFields {
241 pub project: ProjectKey,
242 pub summary: String,
244 pub issuetype: IssueType,
246 #[serde(skip_serializing_if = "Option::is_none")]
248 pub description: Option<serde_json::Value>,
249 #[serde(skip_serializing_if = "Option::is_none")]
250 pub labels: Option<Vec<String>>,
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub priority: Option<PriorityName>,
253 #[serde(skip_serializing_if = "Option::is_none")]
254 pub assignee: Option<serde_json::Value>,
255 #[serde(skip_serializing_if = "Option::is_none")]
257 pub components: Option<Vec<ComponentRef>>,
258 #[serde(skip_serializing_if = "Option::is_none")]
265 pub parent: Option<IssueKeyRef>,
266}
267
268#[derive(Debug, Clone, Serialize, Deserialize)]
278pub struct ComponentRef {
279 pub name: String,
280}
281
282#[derive(Debug, Clone, Serialize)]
284pub struct ProjectKey {
285 pub key: String,
287}
288
289#[derive(Debug, Clone, Serialize)]
291pub struct IssueType {
292 pub name: String,
294}
295
296#[derive(Debug, Clone, Serialize)]
298pub struct PriorityName {
299 pub name: String,
301}
302
303#[derive(Debug, Clone, Serialize)]
305pub struct UpdateIssuePayload {
306 pub fields: UpdateIssueFields,
308}
309
310#[derive(Debug, Clone, Serialize, Default)]
312pub struct UpdateIssueFields {
313 #[serde(skip_serializing_if = "Option::is_none")]
315 pub summary: Option<String>,
316 #[serde(skip_serializing_if = "Option::is_none")]
318 pub description: Option<serde_json::Value>,
319 #[serde(skip_serializing_if = "Option::is_none")]
320 pub labels: Option<Vec<String>>,
321 #[serde(skip_serializing_if = "Option::is_none")]
322 pub priority: Option<PriorityName>,
323 #[serde(skip_serializing_if = "Option::is_none")]
324 pub assignee: Option<serde_json::Value>,
325 #[serde(skip_serializing_if = "Option::is_none")]
328 pub components: Option<Vec<ComponentRef>>,
329}
330
331#[derive(Debug, Clone, Serialize)]
333pub struct TransitionPayload {
334 pub transition: TransitionId,
336}
337
338#[derive(Debug, Clone, Serialize)]
340pub struct TransitionId {
341 pub id: String,
343}
344
345#[derive(Debug, Clone, Deserialize)]
347pub struct CreateIssueResponse {
348 pub id: String,
350 pub key: String,
352}
353
354#[derive(Debug, Clone, Serialize)]
356pub struct AddCommentPayload {
357 pub body: serde_json::Value,
359}
360
361#[derive(Debug, Clone, Deserialize)]
368pub struct JiraIssueTypeStatuses {
369 #[serde(default)]
371 pub name: Option<String>,
372 #[serde(default)]
374 pub statuses: Vec<JiraProjectStatus>,
375}
376
377#[derive(Debug, Clone, Deserialize)]
379#[serde(rename_all = "camelCase")]
380pub struct JiraProjectStatus {
381 pub name: String,
383 #[serde(default)]
385 pub id: Option<String>,
386 #[serde(default)]
387 pub status_category: Option<JiraStatusCategory>,
388}
389
390#[derive(Debug, Clone, Serialize)]
396#[serde(rename_all = "camelCase")]
397pub struct CreateIssueLinkPayload {
398 #[serde(rename = "type")]
399 pub link_type: IssueLinkTypeName,
400 pub inward_issue: IssueKeyRef,
402 pub outward_issue: IssueKeyRef,
404}
405
406#[derive(Debug, Clone, Serialize)]
408pub struct IssueLinkTypeName {
409 pub name: String,
411}
412
413#[derive(Debug, Clone, Serialize)]
415pub struct IssueKeyRef {
416 pub key: String,
418}
419
420#[derive(Debug, Clone, Deserialize)]
426pub struct JiraStructure {
427 pub id: u64,
428 pub name: String,
429 #[serde(default)]
430 pub description: Option<String>,
431}
432
433#[derive(Debug, Clone, Deserialize)]
435pub struct JiraStructureListResponse {
436 pub structures: Vec<JiraStructure>,
437}
438
439#[derive(Debug, Clone, Deserialize)]
441#[serde(rename_all = "camelCase")]
442pub struct JiraForestRow {
443 pub id: u64,
444 #[serde(default)]
445 pub item_id: Option<String>,
446 #[serde(default)]
447 pub item_type: Option<String>,
448}
449
450#[derive(Debug, Clone, Deserialize)]
452#[serde(rename_all = "camelCase")]
453pub struct JiraForestResponse {
454 pub version: u64,
455 #[serde(default)]
456 pub rows: Vec<JiraForestRow>,
457 #[serde(default)]
458 pub depths: Vec<u32>,
459 #[serde(default)]
460 pub total_count: Option<u64>,
461}
462
463#[derive(Debug, Clone, Deserialize)]
465pub struct JiraForestModifyResponse {
466 pub version: u64,
467 #[serde(default)]
468 pub rows: Vec<JiraForestRow>,
469}
470
471#[derive(Debug, Clone, Deserialize)]
473#[serde(rename_all = "camelCase")]
474pub struct JiraStructureView {
475 pub id: u64,
476 pub name: String,
477 pub structure_id: u64,
482 #[serde(default)]
483 pub columns: Vec<JiraStructureViewColumn>,
484 #[serde(default)]
485 pub group_by: Option<String>,
486 #[serde(default)]
487 pub sort_by: Option<String>,
488 #[serde(default)]
489 pub filter: Option<String>,
490}
491
492#[derive(Debug, Clone, Deserialize, Serialize)]
494pub struct JiraStructureViewColumn {
495 #[serde(default)]
496 pub id: Option<String>,
497 #[serde(default)]
498 pub field: Option<String>,
499 #[serde(default)]
500 pub formula: Option<String>,
501 #[serde(default)]
502 pub width: Option<u32>,
503}
504
505#[derive(Debug, Clone, Deserialize)]
507pub struct JiraStructureViewListResponse {
508 pub views: Vec<JiraStructureView>,
509}
510
511#[derive(Debug, Clone, Deserialize)]
513#[serde(rename_all = "camelCase")]
514pub struct JiraStructureValueEntry {
515 pub row_id: u64,
516 #[serde(default)]
517 pub column_id: Option<String>,
518 #[serde(default)]
519 pub value: serde_json::Value,
520}
521
522#[derive(Debug, Clone, Deserialize)]
524pub struct JiraStructureValuesResponse {
525 pub values: Vec<JiraStructureValueEntry>,
526}
527
528#[derive(Debug, Clone, Deserialize)]
538#[serde(rename_all = "camelCase")]
539pub struct JiraVersionDto {
540 pub id: String,
541 pub name: String,
542 #[serde(default)]
545 pub project: Option<String>,
546 #[serde(default)]
547 pub project_id: Option<u64>,
548 #[serde(default)]
549 pub description: Option<String>,
550 #[serde(default)]
551 pub start_date: Option<String>,
552 #[serde(default)]
553 pub release_date: Option<String>,
554 #[serde(default)]
555 pub released: bool,
556 #[serde(default)]
557 pub archived: bool,
558 #[serde(default)]
561 pub overdue: Option<bool>,
562 #[serde(default)]
565 pub issues_status_for_fix_version: Option<JiraVersionIssueStatusCounts>,
566 #[serde(default)]
570 pub issues_unresolved_count: Option<u32>,
571}
572
573#[derive(Debug, Clone, Deserialize, Default)]
575#[serde(rename_all = "camelCase")]
576pub struct JiraVersionIssueStatusCounts {
577 #[serde(default)]
578 pub unmapped: u32,
579 #[serde(default)]
580 pub to_do: u32,
581 #[serde(default)]
582 pub in_progress: u32,
583 #[serde(default)]
584 pub done: u32,
585}
586
587impl JiraVersionIssueStatusCounts {
588 pub fn total(&self) -> u32 {
589 self.unmapped
590 .saturating_add(self.to_do)
591 .saturating_add(self.in_progress)
592 .saturating_add(self.done)
593 }
594}
595
596#[derive(Debug, Clone, Serialize, Default)]
603#[serde(rename_all = "camelCase")]
604pub struct CreateVersionPayload {
605 pub name: String,
606 #[serde(skip_serializing_if = "Option::is_none")]
607 pub project: Option<String>,
608 #[serde(skip_serializing_if = "Option::is_none")]
609 pub project_id: Option<u64>,
610 #[serde(skip_serializing_if = "Option::is_none")]
611 pub description: Option<String>,
612 #[serde(skip_serializing_if = "Option::is_none")]
613 pub start_date: Option<String>,
614 #[serde(skip_serializing_if = "Option::is_none")]
615 pub release_date: Option<String>,
616 #[serde(skip_serializing_if = "Option::is_none")]
617 pub released: Option<bool>,
618 #[serde(skip_serializing_if = "Option::is_none")]
619 pub archived: Option<bool>,
620}
621
622#[derive(Debug, Clone, Serialize, Default)]
626#[serde(rename_all = "camelCase")]
627pub struct UpdateVersionPayload {
628 #[serde(skip_serializing_if = "Option::is_none")]
629 pub name: Option<String>,
630 #[serde(skip_serializing_if = "Option::is_none")]
631 pub description: Option<String>,
632 #[serde(skip_serializing_if = "Option::is_none")]
633 pub start_date: Option<String>,
634 #[serde(skip_serializing_if = "Option::is_none")]
635 pub release_date: Option<String>,
636 #[serde(skip_serializing_if = "Option::is_none")]
637 pub released: Option<bool>,
638 #[serde(skip_serializing_if = "Option::is_none")]
639 pub archived: Option<bool>,
640}