1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use super::attachment::Attachment;
7use super::field::FieldValue;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Issue {
11 pub id: String,
12 pub key: String,
13 pub summary: String,
14 pub description: Option<Value>,
16 pub status: String,
17 pub assignee: Option<String>,
18 pub reporter: Option<String>,
19 pub priority: Option<String>,
20 pub issue_type: String,
21 pub project_key: String,
22 pub created: String,
23 pub updated: String,
24 pub attachments: Vec<Attachment>,
26 pub links: Vec<super::link::IssueLink>,
28 pub fields: Value,
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize, Default)]
33pub struct CreateIssueRequest {
34 pub project_key: String,
35 pub summary: String,
36 pub description: Option<String>,
37 pub issue_type: String,
38 pub assignee: Option<String>,
39 pub priority: Option<String>,
40}
41
42#[derive(Debug, Clone, Default)]
44pub struct CreateIssueRequestV2 {
45 pub project_key: String,
46 pub summary: String,
47 pub description: Option<String>,
49 pub description_adf: Option<Value>,
51 pub issue_type: String,
52 pub assignee: Option<String>,
53 pub priority: Option<String>,
54 pub labels: Vec<String>,
56 pub components: Vec<String>,
58 pub parent: Option<String>,
60 pub fix_versions: Vec<String>,
62 pub custom_fields: HashMap<String, FieldValue>,
64}
65
66#[derive(Debug, Clone, Default)]
67pub struct UpdateIssueRequest {
68 pub summary: Option<String>,
69 pub description: Option<String>,
71 pub description_adf: Option<Value>,
73 pub assignee: Option<String>,
74 pub priority: Option<String>,
75 pub status: Option<String>,
76 pub labels: Option<Vec<String>>,
78 pub components: Option<Vec<String>>,
80 pub fix_versions: Option<Vec<String>>,
82 pub parent: Option<String>,
84 pub custom_fields: HashMap<String, FieldValue>,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct SearchResult {
90 pub issues: Vec<Issue>,
91 pub next_page_token: Option<String>,
92 pub total: Option<u64>,
93}
94
95#[derive(Debug, Deserialize)]
97pub(crate) struct RawIssue {
98 pub id: String,
99 pub key: String,
100 pub fields: Value,
101}
102
103impl RawIssue {
104 pub fn into_issue(self) -> Issue {
105 let fields = &self.fields;
106
107 let summary = fields
108 .get("summary")
109 .and_then(|v| v.as_str())
110 .unwrap_or("")
111 .to_string();
112
113 let description = fields.get("description").cloned();
114
115 let status = fields
116 .get("status")
117 .and_then(|v| v.get("name"))
118 .and_then(|v| v.as_str())
119 .unwrap_or("Unknown")
120 .to_string();
121
122 let assignee = fields
123 .get("assignee")
124 .and_then(|v| v.get("emailAddress").or_else(|| v.get("displayName")))
125 .and_then(|v| v.as_str())
126 .map(|s| s.to_string());
127
128 let reporter = fields
129 .get("reporter")
130 .and_then(|v| v.get("emailAddress").or_else(|| v.get("displayName")))
131 .and_then(|v| v.as_str())
132 .map(|s| s.to_string());
133
134 let priority = fields
135 .get("priority")
136 .and_then(|v| v.get("name"))
137 .and_then(|v| v.as_str())
138 .map(|s| s.to_string());
139
140 let issue_type = fields
141 .get("issuetype")
142 .and_then(|v| v.get("name"))
143 .and_then(|v| v.as_str())
144 .unwrap_or("Unknown")
145 .to_string();
146
147 let project_key = fields
148 .get("project")
149 .and_then(|v| v.get("key"))
150 .and_then(|v| v.as_str())
151 .unwrap_or("")
152 .to_string();
153
154 let created = fields
155 .get("created")
156 .and_then(|v| v.as_str())
157 .unwrap_or("")
158 .to_string();
159
160 let updated = fields
161 .get("updated")
162 .and_then(|v| v.as_str())
163 .unwrap_or("")
164 .to_string();
165
166 let attachments = fields
167 .get("attachment")
168 .and_then(|v| v.as_array())
169 .map(|arr| arr.iter().filter_map(Attachment::from_value).collect())
170 .unwrap_or_default();
171
172 let links = fields
173 .get("issuelinks")
174 .and_then(|v| v.as_array())
175 .map(|arr| {
176 arr.iter()
177 .filter_map(super::link::IssueLink::from_value)
178 .collect()
179 })
180 .unwrap_or_default();
181
182 Issue {
183 id: self.id,
184 key: self.key,
185 summary,
186 description,
187 status,
188 assignee,
189 reporter,
190 priority,
191 issue_type,
192 project_key,
193 created,
194 updated,
195 attachments,
196 links,
197 fields: self.fields,
198 }
199 }
200}
201
202#[derive(Debug, Deserialize)]
204pub(crate) struct RawSearchResponse {
205 pub issues: Vec<RawIssue>,
206 #[serde(rename = "nextPageToken")]
207 pub next_page_token: Option<String>,
208 pub total: Option<u64>,
209}