Skip to content

Commit feb268e

Browse files
authored
Update quickxml to 0.38 (#33)
The biggest change here is that newer quick-xml differentiate between attributes and elements. Specifically attributes needs to be named `@name` now.
2 parents 64a11a5 + 985966f commit feb268e

File tree

8 files changed

+139
-59
lines changed

8 files changed

+139
-59
lines changed

open-build-service-api/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ license = "MIT OR Apache-2.0"
1010
[dependencies]
1111
reqwest = { version = "0.11.27", features = [ "stream" ] }
1212
url = "2.5.4"
13-
quick-xml = { version = "0.23.1", features = [ "serialize" ] }
14-
serde = { version = "1.0.125", features = [ "derive" ] }
13+
quick-xml = { version = "0.38", features = [ "serialize" ] }
14+
serde = { version = "1.0.217", features = [ "derive" ] }
1515
chrono = { version = "0.4", features = [ "serde" ] }
1616
thiserror = "2.0.12"
1717
futures = "0.3.14"

open-build-service-api/src/lib.rs

Lines changed: 105 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use futures::prelude::*;
44
use futures::ready;
55
use futures::stream::BoxStream;
66
use md5::{Digest, Md5};
7+
use quick_xml::SeError;
8+
use quick_xml::name::QName;
79
use quick_xml::{de::DeError, events::Event};
810
use reqwest::{Body, Method, RequestBuilder, Response, header::CONTENT_TYPE};
911
use serde::de::IntoDeserializer;
@@ -21,6 +23,8 @@ pub enum Error {
2123
RequestError(#[from] reqwest::Error),
2224
#[error("Request deserialization failed: {0}")]
2325
DeError(#[from] DeError),
26+
#[error("Request serialization failed: {0}")]
27+
SeError(#[from] SeError),
2428
#[error("{0}")]
2529
ApiError(ApiError),
2630
#[error("Unexpected result")]
@@ -37,6 +41,7 @@ pub struct ApiErrorSummary {
3741

3842
#[derive(Clone, Deserialize, Debug)]
3943
pub struct ApiError {
44+
#[serde(rename = "@code")]
4045
pub code: String,
4146
pub summary: ApiErrorSummary,
4247
}
@@ -71,10 +76,11 @@ pub enum BlockMode {
7176

7277
#[derive(Deserialize, Debug)]
7378
pub struct RepositoryMeta {
79+
#[serde(rename = "@name")]
7480
pub name: String,
75-
#[serde(default)]
81+
#[serde(default, rename = "@rebuild")]
7682
pub rebuild: RebuildMode,
77-
#[serde(default)]
83+
#[serde(default, rename = "@block")]
7884
pub block: BlockMode,
7985

8086
#[serde(default, rename = "arch")]
@@ -83,6 +89,7 @@ pub struct RepositoryMeta {
8389

8490
#[derive(Deserialize, Debug)]
8591
pub struct ProjectMeta {
92+
#[serde(rename = "@name")]
8693
pub name: String,
8794
#[serde(default, rename = "repository")]
8895
pub repositories: Vec<RepositoryMeta>,
@@ -158,20 +165,28 @@ pub struct JobStatus {
158165

159166
#[derive(Deserialize, Debug)]
160167
pub struct BuildStatus {
168+
#[serde(rename = "@package")]
161169
pub package: String,
170+
#[serde(rename = "@code")]
162171
pub code: PackageCode,
163-
#[serde(default)]
172+
#[serde(default, rename = "@dirty")]
164173
pub dirty: bool,
165174
pub details: Option<String>,
166175
}
167176

168177
#[derive(Deserialize, Debug)]
169178
pub struct BuildHistoryEntry {
179+
#[serde(rename = "@rev")]
170180
pub rev: String,
181+
#[serde(rename = "@srcmd5")]
171182
pub srcmd5: String,
183+
#[serde(rename = "@versrel")]
172184
pub versrel: String,
185+
#[serde(rename = "@bcnt")]
173186
pub bcnt: String,
187+
#[serde(rename = "@time")]
174188
pub time: String,
189+
#[serde(rename = "@duration")]
175190
pub duration: String,
176191
}
177192

@@ -183,32 +198,58 @@ pub struct BuildHistory {
183198

184199
#[derive(Deserialize, Debug)]
185200
pub struct LinkInfo {
201+
#[serde(rename = "@project")]
186202
pub project: String,
203+
#[serde(rename = "@package")]
187204
pub package: String,
205+
#[serde(rename = "@srcmd5")]
188206
pub srcmd5: String,
207+
#[serde(rename = "@xsrcmd5")]
189208
pub xsrcmd5: String,
209+
#[serde(rename = "@lsrcmd5")]
190210
pub lsrcmd5: String,
191-
#[serde(default)]
211+
#[serde(default, rename = "@missingok")]
192212
pub missingok: bool,
193213
}
194214

195215
#[derive(Deserialize, Debug)]
196216
pub struct SourceDirectoryEntry {
217+
#[serde(rename = "@name")]
197218
pub name: String,
219+
#[serde(rename = "@size")]
198220
pub size: u64,
221+
#[serde(rename = "@md5")]
199222
pub md5: String,
223+
#[serde(rename = "@mtime")]
200224
pub mtime: u64,
225+
#[serde(rename = "@originproject")]
201226
pub originproject: Option<String>,
202227
//available ?
203228
//recommended ?
229+
#[serde(rename = "@hash")]
204230
pub hash: Option<String>,
205231
}
206232

233+
fn empty_string_is_none<'de, D>(de: D) -> std::result::Result<Option<String>, D::Error>
234+
where
235+
D: serde::Deserializer<'de>,
236+
{
237+
let s = Option::deserialize(de)?;
238+
match s.as_deref() {
239+
Some("") => Ok(None),
240+
_ => Ok(s),
241+
}
242+
}
243+
207244
#[derive(Deserialize, Debug)]
208245
pub struct SourceDirectory {
246+
#[serde(rename = "@name")]
209247
pub name: String,
248+
#[serde(rename = "@rev")]
210249
pub rev: Option<String>,
250+
#[serde(default, rename = "@vrev", deserialize_with = "empty_string_is_none")]
211251
pub vrev: Option<String>,
252+
#[serde(rename = "@srcmd5")]
212253
pub srcmd5: String,
213254
#[serde(default, rename = "entry")]
214255
pub entries: Vec<SourceDirectoryEntry>,
@@ -218,7 +259,9 @@ pub struct SourceDirectory {
218259

219260
#[derive(Clone, Deserialize, Debug)]
220261
pub struct Revision {
262+
#[serde(rename = "@rev")]
221263
pub rev: String,
264+
#[serde(rename = "@vrev")]
222265
pub vrev: String,
223266
pub srcmd5: String,
224267
pub version: String,
@@ -235,14 +278,16 @@ pub struct RevisionList {
235278

236279
#[derive(Clone, Deserialize, Serialize, Debug)]
237280
pub struct CommitEntry {
281+
#[serde(rename = "@name")]
238282
pub name: String,
283+
#[serde(rename = "@md5")]
239284
pub md5: String,
240285
}
241286

242287
impl CommitEntry {
243-
pub fn from_contents<T: AsRef<[u8]>>(name: String, contents: T) -> CommitEntry {
288+
pub fn from_contents<T: AsRef<[u8]>>(name: String, contents: T) -> Self {
244289
let md5 = base16ct::lower::encode_string(&Md5::digest(&contents));
245-
CommitEntry { name, md5 }
290+
Self { name, md5 }
246291
}
247292
}
248293

@@ -259,31 +304,44 @@ pub enum CommitResult {
259304
MissingEntries(MissingEntries),
260305
}
261306

307+
#[derive(Clone, Deserialize, Serialize, Debug)]
308+
pub struct CommitFileEntry {
309+
pub name: String,
310+
pub md5: String,
311+
}
312+
313+
impl CommitFileEntry {
314+
pub fn from_contents<T: AsRef<[u8]>>(name: String, contents: T) -> Self {
315+
let md5 = base16ct::lower::encode_string(&Md5::digest(&contents));
316+
Self { name, md5 }
317+
}
318+
}
319+
262320
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
263321
#[serde(rename = "directory")]
264322
pub struct CommitFileList {
265323
#[serde(rename = "entry")]
266-
entries: Vec<CommitEntry>,
324+
entries: Vec<CommitFileEntry>,
267325
}
268326

269327
impl CommitFileList {
270328
pub fn new() -> Self {
271329
CommitFileList::default()
272330
}
273331

274-
pub fn add_entry(&mut self, entry: CommitEntry) {
332+
pub fn add_entry(&mut self, entry: CommitFileEntry) {
275333
self.entries.push(entry);
276334
}
277335

278336
pub fn add_file_md5(&mut self, name: String, md5: String) {
279-
self.add_entry(CommitEntry { name, md5 });
337+
self.add_entry(CommitFileEntry { name, md5 });
280338
}
281339

282340
pub fn add_file_from_contents(&mut self, name: String, contents: &[u8]) {
283-
self.add_entry(CommitEntry::from_contents(name, contents));
341+
self.add_entry(CommitFileEntry::from_contents(name, contents));
284342
}
285343

286-
pub fn entry(mut self, entry: CommitEntry) -> Self {
344+
pub fn entry(mut self, entry: CommitFileEntry) -> Self {
287345
self.add_entry(entry);
288346
self
289347
}
@@ -331,6 +389,7 @@ impl<'de> Deserialize<'de> for BranchStatus {
331389
{
332390
#[derive(Deserialize)]
333391
struct BranchStatusDataItem {
392+
#[serde(rename = "@name")]
334393
name: String,
335394
#[serde(rename = "$value")]
336395
value: String,
@@ -367,9 +426,9 @@ impl<'de> Deserialize<'de> for BranchStatus {
367426

368427
#[derive(Deserialize, Debug)]
369428
pub struct PackageBuildMetaDisable {
370-
#[serde(default)]
429+
#[serde(default, rename = "@repository")]
371430
pub repository: Option<String>,
372-
#[serde(default)]
431+
#[serde(default, rename = "@arch")]
373432
pub arch: Option<String>,
374433
}
375434

@@ -381,19 +440,25 @@ pub struct PackageBuildMeta {
381440

382441
#[derive(Deserialize, Debug)]
383442
pub struct PackageMeta {
443+
#[serde(rename = "@name")]
384444
pub name: String,
445+
#[serde(rename = "@project")]
385446
pub project: String,
386447
#[serde(default)]
387448
pub build: PackageBuildMeta,
388449
}
389450

390451
#[derive(Deserialize, Debug)]
391452
pub struct ResultListResult {
453+
#[serde(rename = "@project")]
392454
pub project: String,
455+
#[serde(rename = "@repository")]
393456
pub repository: String,
457+
#[serde(rename = "@arch")]
394458
pub arch: String,
459+
#[serde(rename = "@code")]
395460
pub code: RepositoryCode,
396-
#[serde(default)]
461+
#[serde(default, rename = "@dirty")]
397462
pub dirty: bool,
398463
#[serde(default, rename = "status")]
399464
pub statuses: Vec<BuildStatus>,
@@ -407,15 +472,19 @@ impl ResultListResult {
407472

408473
#[derive(Deserialize, Debug)]
409474
pub struct ResultList {
475+
#[serde(rename = "@state")]
410476
pub state: String,
411477
#[serde(rename = "result")]
412478
pub results: Vec<ResultListResult>,
413479
}
414480

415481
#[derive(Clone, Deserialize, Debug)]
416482
pub struct Binary {
483+
#[serde(rename = "@filename")]
417484
pub filename: String,
485+
#[serde(rename = "@size")]
418486
pub size: u64,
487+
#[serde(rename = "@mtime")]
419488
pub mtime: u64,
420489
}
421490

@@ -427,6 +496,7 @@ pub struct BinaryList {
427496

428497
#[derive(Deserialize, Debug)]
429498
pub struct DirectoryEntry {
499+
#[serde(rename = "@name")]
430500
pub name: String,
431501
}
432502

@@ -508,19 +578,33 @@ impl JobHistoryFilters {
508578

509579
#[derive(Deserialize, Debug)]
510580
pub struct JobHist {
581+
#[serde(rename = "@package")]
511582
pub package: String,
583+
#[serde(rename = "@rev")]
512584
pub rev: String,
585+
#[serde(rename = "@srcmd5")]
513586
pub srcmd5: String,
587+
#[serde(rename = "@versrel")]
514588
pub versrel: String,
589+
#[serde(rename = "@bcnt")]
515590
pub bcnt: String,
591+
#[serde(rename = "@readytime")]
516592
pub readytime: u64,
593+
#[serde(rename = "@starttime")]
517594
pub starttime: u64,
595+
#[serde(rename = "@endtime")]
518596
pub endtime: u64,
597+
#[serde(rename = "@code")]
519598
pub code: PackageCode,
599+
#[serde(rename = "@uri")]
520600
pub uri: String,
601+
#[serde(rename = "@workerid")]
521602
pub workerid: String,
603+
#[serde(rename = "@hostarch")]
522604
pub hostarch: String,
605+
#[serde(rename = "@reason")]
523606
pub reason: String,
607+
#[serde(rename = "@verifymd5")]
524608
pub verifymd5: String,
525609
}
526610

@@ -532,7 +616,9 @@ pub struct JobHistList {
532616

533617
#[derive(Deserialize, Debug)]
534618
struct LogEntryEntry {
619+
#[serde(rename = "@size")]
535620
size: usize,
621+
#[serde(rename = "@mtime")]
536622
mtime: u64,
537623
}
538624

@@ -931,7 +1017,7 @@ impl<'a> PackageBuilder<'a> {
9311017
u.query_pairs_mut().append_pair("comment", comment);
9321018
}
9331019

934-
let mut body = Vec::new();
1020+
let mut body = String::new();
9351021
quick_xml::se::to_writer(&mut body, filelist)?;
9361022

9371023
let response = Client::send_with_error(
@@ -958,13 +1044,12 @@ impl<'a> PackageBuilder<'a> {
9581044
// "Deserialize".
9591045

9601046
let mut reader = quick_xml::Reader::from_str(&response);
961-
reader.trim_text(true);
962-
let mut buf = Vec::new();
963-
if let Event::Start(e) = reader.read_event(&mut buf).map_err(DeError::from)? {
1047+
reader.config_mut().trim_text(true);
1048+
if let Event::Start(e) = reader.read_event().map_err(DeError::from)? {
9641049
let mut is_missing = false;
9651050
for attr in e.attributes() {
9661051
let attr = attr.map_err(DeError::from)?;
967-
if attr.key == b"error" {
1052+
if attr.key == QName(b"error") {
9681053
if attr.value.as_ref() != b"missing" {
9691054
return Err(DeError::Custom(
9701055
"only supported value for 'error' is 'missing'".to_owned(),
@@ -983,7 +1068,7 @@ impl<'a> PackageBuilder<'a> {
9831068
CommitResult::Success(quick_xml::de::from_str(&response)?)
9841069
})
9851070
} else {
986-
Err(DeError::Start.into())
1071+
Err(DeError::UnexpectedStart(response.into()).into())
9871072
}
9881073
}
9891074

open-build-service-api/tests/integration.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ async fn test_source_list() {
205205

206206
assert_eq!(meta_dir.name, TEST_PACKAGE_1);
207207
assert_eq!(meta_dir.rev.unwrap(), "1");
208-
assert!(meta_dir.vrev.is_none());
208+
assert_eq!(meta_dir.vrev, None, "unexpected vrev");
209209
let mtime = SystemTime::UNIX_EPOCH + Duration::from_secs(10);
210210
let srcmd5 = random_md5();
211211
mock.add_package_revision(
@@ -416,7 +416,7 @@ async fn test_source_get() {
416416
async fn test_commits() {
417417
let test_file = "test";
418418
let test_contents = b"some file contents here";
419-
let test_entry = CommitEntry::from_contents(test_file.to_owned(), test_contents);
419+
let test_entry = CommitFileEntry::from_contents(test_file.to_owned(), test_contents);
420420

421421
let file_list = CommitFileList::new().entry(test_entry.clone());
422422

0 commit comments

Comments
 (0)