1use std::fmt;
22
23use chrono::{DateTime, NaiveDate, Utc};
24use serde::Deserialize;
25use serde_json::Value;
26
27#[derive(Clone, Debug, Deserialize)]
30pub struct Response {
31 pub offset: Option<u32>,
32 pub limit: Option<String>,
33 pub total_matches: Option<u32>,
34 pub bugs: Vec<Bug>,
35 #[serde(flatten)]
36 pub extra: Value,
37}
38
39#[derive(Clone, Debug, Deserialize)]
41pub struct BugzillaError {
42 pub error: bool,
43 pub message: String,
44 pub code: i32,
45 #[serde(flatten)]
46 pub extra: Value,
47}
48
49#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
51#[serde(untagged)]
52pub enum OneOrMany {
53 None,
54 One(String),
55 Many(Vec<String>),
56}
57
58impl OneOrMany {
59 pub fn into_vec(self) -> Vec<String> {
61 match self {
62 Self::None => Vec::new(),
63 Self::One(s) => vec![s],
64 Self::Many(v) => v,
65 }
66 }
67}
68
69pub type Component = OneOrMany;
71
72pub type Version = OneOrMany;
74
75pub type Alias = OneOrMany;
77
78#[allow(clippy::struct_excessive_bools)]
80#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
81pub struct Bug {
82 pub alias: Alias,
83 pub op_sys: String,
84 pub classification: String,
85 pub id: i32,
86 pub url: String,
87 pub creator: String,
88 pub creator_detail: User,
89 pub summary: String,
90 pub status: String,
91 pub estimated_time: Option<i64>,
92 pub target_milestone: String,
93 pub cc: Vec<String>,
94 pub cc_detail: Vec<User>,
95 pub is_open: bool,
96 pub is_creator_accessible: bool,
97 pub docs_contact: Option<String>,
98 pub docs_contact_detail: Option<User>,
99 pub assigned_to: String,
100 pub assigned_to_detail: User,
101 pub resolution: String,
102 pub severity: String,
103 pub product: String,
104 pub platform: String,
105 pub last_change_time: DateTime<Utc>,
106 pub remaining_time: Option<i64>,
107 pub priority: String,
108 pub whiteboard: String,
109 pub creation_time: DateTime<Utc>,
110 pub is_confirmed: bool,
111 pub qa_contact: String,
112 pub qa_contact_detail: Option<User>,
113 pub dupe_of: Option<i32>,
114 pub target_release: Option<Version>,
115 pub actual_time: Option<i64>,
116 pub component: Component,
117 pub is_cc_accessible: bool,
118 pub version: Version,
119 pub keywords: Vec<String>,
120 pub depends_on: Vec<i32>,
121 pub blocks: Vec<i32>,
122 pub see_also: Option<Vec<String>>,
123 pub groups: Vec<String>,
124 pub deadline: Option<NaiveDate>,
126 pub update_token: Option<String>,
127 pub work_time: Option<i64>,
128 pub flags: Option<Vec<Flag>>,
130 pub tags: Option<Vec<String>>,
131 pub dependent_products: Option<Vec<String>>,
132 #[serde(flatten)]
133 pub extra: Value,
134}
135
136#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
138pub struct User {
139 pub email: String,
140 pub id: i32,
141 pub name: String,
142 pub real_name: String,
143 #[serde(flatten)]
144 pub extra: Value,
145}
146
147#[derive(Clone, Debug, Deserialize, PartialEq, Eq)]
151pub struct Flag {
152 pub id: i32,
153 pub type_id: i32,
154 pub creation_date: DateTime<Utc>,
155 pub modification_date: DateTime<Utc>,
156 pub name: String,
157 pub status: String,
158 pub setter: String,
159 pub requestee: Option<String>,
160 #[serde(flatten)]
161 pub extra: Value,
162}
163
164impl fmt::Display for Flag {
165 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
166 write!(f, "{}: {}", self.name, self.status)
168 }
169}