rebuilderd_common/api/v1/models/
build.rs1use chrono::NaiveDateTime;
2#[cfg(feature = "diesel")]
3use diesel::{
4 AsExpression, FromSqlRow, Queryable, deserialize::FromSql, serialize::Output, serialize::ToSql,
5 sql_types::Text, sqlite::Sqlite, sqlite::SqliteValue,
6};
7use serde::{Deserialize, Serialize};
8use std::error::Error;
9use std::fmt;
10use std::fmt::Formatter;
11
12#[derive(Debug, Serialize, Deserialize)]
13pub struct RebuildReport {
14 pub queue_id: i32,
15 pub built_at: NaiveDateTime,
16 pub build_log: Vec<u8>,
17 pub status: BuildStatus,
18 pub artifacts: Vec<RebuildArtifactReport>,
19}
20
21#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, clap::ValueEnum)]
22#[cfg_attr(feature = "diesel", derive(FromSqlRow, AsExpression))]
23#[cfg_attr(feature = "diesel", diesel(sql_type = Text))]
24#[cfg_attr(feature = "diesel", diesel(check_for_backend(diesel::sqlite::Sqlite)))]
25pub enum BuildStatus {
26 #[serde(rename = "GOOD")]
27 #[clap(name = "GOOD")]
28 Good,
29
30 #[serde(rename = "BAD")]
31 #[clap(name = "BAD")]
32 Bad,
33
34 #[serde(rename = "FAIL")]
35 #[clap(name = "FAIL")]
36 Fail,
37
38 #[serde(rename = "UNKWN")]
39 #[clap(name = "UNKWN")]
40 Unknown,
41}
42
43impl BuildStatus {
44 pub fn as_str(&self) -> &str {
45 match self {
46 BuildStatus::Good => "GOOD",
47 BuildStatus::Bad => "BAD",
48 BuildStatus::Fail => "FAIL",
49 BuildStatus::Unknown => "UNKWN",
50 }
51 }
52}
53
54#[derive(Debug, Clone)]
55pub struct BuildStatusParseError {
56 value: String,
57}
58
59impl fmt::Display for BuildStatusParseError {
60 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
61 let value = &self.value;
62 write!(f, "could not parse \"{value}\" as a build status")
63 }
64}
65
66impl Error for BuildStatusParseError {}
67
68impl TryFrom<&str> for BuildStatus {
69 type Error = BuildStatusParseError;
70
71 fn try_from(value: &str) -> Result<Self, Self::Error> {
72 match value {
73 "GOOD" => Ok(BuildStatus::Good),
74 "BAD" => Ok(BuildStatus::Bad),
75 "FAIL" => Ok(BuildStatus::Fail),
76 "UNKWN" => Ok(BuildStatus::Unknown),
77 _ => Err(BuildStatusParseError {
78 value: value.to_string(),
79 }),
80 }
81 }
82}
83
84#[cfg(feature = "diesel")]
85impl FromSql<Text, Sqlite> for BuildStatus {
86 fn from_sql(bytes: SqliteValue) -> diesel::deserialize::Result<Self> {
87 let t = <String as FromSql<Text, Sqlite>>::from_sql(bytes)?;
88 Ok(t.as_str().try_into()?)
89 }
90}
91
92#[cfg(feature = "diesel")]
93impl ToSql<Text, Sqlite> for BuildStatus {
94 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> diesel::serialize::Result {
95 out.set_value(self.as_str());
96 Ok(diesel::serialize::IsNull::No)
97 }
98}
99
100#[derive(Debug, Serialize, Deserialize)]
101pub struct RebuildArtifactReport {
102 pub name: String,
103 pub diffoscope: Option<Vec<u8>>,
104 pub attestation: Option<Vec<u8>>,
105 pub status: ArtifactStatus,
106}
107
108#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, clap::ValueEnum)]
109#[cfg_attr(feature = "diesel", derive(FromSqlRow, AsExpression))]
110#[cfg_attr(feature = "diesel", diesel(sql_type = Text))]
111#[cfg_attr(feature = "diesel", diesel(check_for_backend(diesel::sqlite::Sqlite)))]
112pub enum ArtifactStatus {
113 #[serde(rename = "GOOD")]
114 #[clap(name = "GOOD")]
115 Good,
116
117 #[serde(rename = "BAD")]
118 #[clap(name = "BAD")]
119 Bad,
120
121 #[serde(rename = "UNKWN")]
122 #[clap(name = "UNKWN")]
123 Unknown,
124}
125
126impl ArtifactStatus {
127 pub fn as_str(&self) -> &str {
128 match self {
129 ArtifactStatus::Good => "GOOD",
130 ArtifactStatus::Bad => "BAD",
131 ArtifactStatus::Unknown => "UNKWN",
132 }
133 }
134}
135
136#[derive(Debug, Clone)]
137pub struct ArtifactStatusParseError {
138 value: String,
139}
140
141impl fmt::Display for ArtifactStatusParseError {
142 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
143 let value = &self.value;
144 write!(f, "could not parse \"{value}\" as an artifact status")
145 }
146}
147
148impl Error for ArtifactStatusParseError {}
149
150impl TryFrom<&str> for ArtifactStatus {
151 type Error = ArtifactStatusParseError;
152
153 fn try_from(value: &str) -> Result<Self, Self::Error> {
154 match value {
155 "GOOD" => Ok(ArtifactStatus::Good),
156 "BAD" => Ok(ArtifactStatus::Bad),
157 "UNKWN" => Ok(ArtifactStatus::Unknown),
158 _ => Err(ArtifactStatusParseError {
159 value: value.to_string(),
160 }),
161 }
162 }
163}
164
165#[cfg(feature = "diesel")]
166impl FromSql<Text, Sqlite> for ArtifactStatus {
167 fn from_sql(bytes: SqliteValue) -> diesel::deserialize::Result<Self> {
168 let t = <String as FromSql<Text, Sqlite>>::from_sql(bytes)?;
169 Ok(t.as_str().try_into()?)
170 }
171}
172
173#[cfg(feature = "diesel")]
174impl ToSql<Text, Sqlite> for ArtifactStatus {
175 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> diesel::serialize::Result {
176 out.set_value(self.as_str());
177 Ok(diesel::serialize::IsNull::No)
178 }
179}
180
181#[derive(Debug, Serialize, Deserialize)]
182#[cfg_attr(feature = "diesel", derive(Queryable))]
183#[cfg_attr(feature = "diesel", diesel(check_for_backend(diesel::sqlite::Sqlite)))]
184pub struct Rebuild {
185 pub id: i32,
186 pub name: String,
187 pub version: String,
188 pub distribution: String,
189 pub release: Option<String>,
190 pub component: Option<String>,
191 pub architecture: String,
192 pub backend: String,
193 pub retries: i32,
194 pub started_at: Option<NaiveDateTime>,
195 pub built_at: Option<NaiveDateTime>,
196 pub status: Option<BuildStatus>,
197}
198
199#[derive(Debug, Serialize, Deserialize)]
200#[cfg_attr(feature = "diesel", derive(Queryable))]
201#[cfg_attr(feature = "diesel", diesel(check_for_backend(diesel::sqlite::Sqlite)))]
202pub struct RebuildArtifact {
203 pub id: i32,
204 pub name: String,
205 pub has_diffoscope: bool,
206 pub has_attestation: bool,
207 pub status: Option<ArtifactStatus>,
208}