Skip to content

Commit c1aab98

Browse files
ref(dif): Make poll_assemble generic
1 parent c3c0a26 commit c1aab98

File tree

3 files changed

+87
-44
lines changed

3 files changed

+87
-44
lines changed

src/utils/chunks/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
88
mod types;
99

10-
pub use types::{Chunked, MissingObjectsInfo};
10+
pub use types::{Chunked, MissingObjectsInfo, Named};
1111

1212
use std::sync::Arc;
1313
use std::time::Duration;

src/utils/chunks/types.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Contains data types used in the chunk upload process.
22
3+
use std::fmt::{Display, Formatter, Result as FmtResult};
4+
35
use anyhow::Result;
46
use sha1_smol::Digest;
57

@@ -10,6 +12,12 @@ use crate::utils::fs;
1012
/// objects and their missing chunks.
1113
pub type MissingObjectsInfo<'m, T> = (Vec<&'m Chunked<T>>, Vec<Chunk<'m>>);
1214

15+
/// A trait for objects that have a name.
16+
pub trait Named {
17+
/// Returns the name of the object.
18+
fn name(&self) -> &str;
19+
}
20+
1321
/// Chunked arbitrary data with computed SHA1 checksums.
1422
pub struct Chunked<T> {
1523
/// Original object
@@ -69,3 +77,21 @@ where
6977
.map(|(data, checksum)| Chunk((*checksum, data)))
7078
}
7179
}
80+
81+
impl<T> Display for Chunked<T>
82+
where
83+
T: Display,
84+
{
85+
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
86+
write!(f, "{}", self.object())
87+
}
88+
}
89+
90+
impl<T> Named for Chunked<T>
91+
where
92+
T: Named,
93+
{
94+
fn name(&self) -> &str {
95+
self.object().name()
96+
}
97+
}

src/utils/dif_upload.rs

Lines changed: 60 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use std::collections::{BTreeMap, BTreeSet};
55
use std::convert::TryInto;
66
use std::ffi::{OsStr, OsString};
7-
use std::fmt::{self, Display};
7+
use std::fmt::{self, Display, Formatter};
88
use std::fs::{self, File};
99
use std::io::{BufReader, BufWriter, Read, Seek, Write};
1010
use std::iter::IntoIterator;
@@ -38,7 +38,7 @@ use crate::api::{
3838
use crate::config::Config;
3939
use crate::constants::{DEFAULT_MAX_DIF_SIZE, DEFAULT_MAX_WAIT};
4040
use crate::utils::chunks::{
41-
upload_chunks, BatchedSliceExt, Chunk, Chunked, ItemSize, MissingObjectsInfo,
41+
upload_chunks, BatchedSliceExt, Chunk, Chunked, ItemSize, MissingObjectsInfo, Named,
4242
ASSEMBLE_POLL_INTERVAL,
4343
};
4444
use crate::utils::dif::ObjectDifFeatures;
@@ -273,6 +273,44 @@ impl AsRef<[u8]> for DifMatch<'_> {
273273
}
274274
}
275275

276+
impl Display for DifMatch<'_> {
277+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
278+
let kind = match self.dif.get() {
279+
ParsedDif::Object(ref object) => match object.kind() {
280+
symbolic::debuginfo::ObjectKind::None => String::new(),
281+
k => format!(" {k:#}"),
282+
},
283+
ParsedDif::BcSymbolMap => String::from("bcsymbolmap"),
284+
ParsedDif::UuidMap => String::from("uuidmap"),
285+
ParsedDif::Il2Cpp => String::from("il2cpp"),
286+
};
287+
288+
write!(
289+
f,
290+
"{} ({}; {}{})",
291+
style(self.debug_id.map(|id| id.to_string()).unwrap_or_default()).dim(),
292+
self.name,
293+
self.object()
294+
.map(|object| {
295+
let arch = object.arch();
296+
match arch {
297+
Arch::Unknown => String::new(),
298+
_ => arch.to_string(),
299+
}
300+
})
301+
.unwrap_or_default(),
302+
kind,
303+
)
304+
}
305+
}
306+
307+
impl Named for DifMatch<'_> {
308+
/// A DIF's name is its file name.
309+
fn name(&self) -> &str {
310+
self.file_name()
311+
}
312+
}
313+
276314
/// A tuple which can be collected into a mapping of checksums to
277315
/// `ChunkedDifRequest`s. The collected mapping can be sent in a
278316
/// request to the assemble endpoint.
@@ -1361,23 +1399,27 @@ fn render_detail(detail: &Option<String>, fallback: Option<&str>) {
13611399
///
13621400
/// This function assumes that all chunks have been uploaded successfully. If there are still
13631401
/// missing chunks in the assemble response, this likely indicates a bug in the server.
1364-
fn poll_dif_assemble(
1365-
difs: &[&Chunked<DifMatch<'_>>],
1402+
fn poll_assemble<T>(
1403+
chunked_objects: &[&Chunked<T>],
13661404
options: &DifUpload,
1367-
) -> Result<(Vec<DebugInfoFile>, bool)> {
1405+
) -> Result<(Vec<DebugInfoFile>, bool)>
1406+
where
1407+
T: Display + Named,
1408+
Chunked<T>: IntoAssembleRequest,
1409+
{
13681410
let progress_style = ProgressStyle::default_bar().template(
13691411
"{prefix:.dim} Processing files...\
13701412
\n{wide_bar} {pos}/{len}",
13711413
);
13721414

13731415
let api = Api::current();
1374-
let pb = ProgressBar::new(difs.len());
1416+
let pb = ProgressBar::new(chunked_objects.len());
13751417
pb.set_style(progress_style);
13761418
pb.set_prefix(">");
13771419

13781420
let assemble_start = Instant::now();
13791421

1380-
let request = difs
1422+
let request = chunked_objects
13811423
.iter()
13821424
.map(|d| d.assemble_request(options.pdbs_allowed))
13831425
.collect();
@@ -1413,7 +1455,7 @@ fn poll_dif_assemble(
14131455
.filter(|&(_, r)| r.state.is_pending())
14141456
.count();
14151457

1416-
pb.set_position((difs.len() - pending) as u64);
1458+
pb.set_position((chunked_objects.len() - pending) as u64);
14171459

14181460
if pending == 0 {
14191461
break response;
@@ -1444,7 +1486,8 @@ fn poll_dif_assemble(
14441486
.to_owned()
14451487
});
14461488

1447-
let difs_by_checksum: BTreeMap<_, _> = difs.iter().map(|m| (m.checksum(), m)).collect();
1489+
let objects_by_checksum: BTreeMap<_, _> =
1490+
chunked_objects.iter().map(|m| (m.checksum(), m)).collect();
14481491

14491492
for &(checksum, ref success) in &successes {
14501493
// Silently skip all OK entries without a "dif" record since the server
@@ -1462,60 +1505,34 @@ fn poll_dif_assemble(
14621505
);
14631506

14641507
render_detail(&success.detail, None);
1465-
} else if let Some(dif) = difs_by_checksum.get(&checksum) {
1508+
} else if let Some(object) = objects_by_checksum.get(&checksum) {
14661509
// If we skip waiting for the server to finish processing, there
14671510
// are pending entries. We only expect results that have been
14681511
// uploaded in the first place, so we can skip everything else.
1469-
let dif = dif.object();
1470-
let kind = match dif.dif.get() {
1471-
ParsedDif::Object(ref object) => match object.kind() {
1472-
symbolic::debuginfo::ObjectKind::None => String::new(),
1473-
k => format!(" {k:#}"),
1474-
},
1475-
ParsedDif::BcSymbolMap => String::from("bcsymbolmap"),
1476-
ParsedDif::UuidMap => String::from("uuidmap"),
1477-
ParsedDif::Il2Cpp => String::from("il2cpp"),
1478-
};
1479-
1480-
println!(
1481-
" {:>8} {} ({}; {}{})",
1482-
style("UPLOADED").yellow(),
1483-
style(dif.debug_id.map(|id| id.to_string()).unwrap_or_default()).dim(),
1484-
dif.name,
1485-
dif.object()
1486-
.map(|object| {
1487-
let arch = object.arch();
1488-
match arch {
1489-
Arch::Unknown => String::new(),
1490-
_ => arch.to_string(),
1491-
}
1492-
})
1493-
.unwrap_or_default(),
1494-
kind,
1495-
);
1512+
println!(" {:>8} {}", style("UPLOADED").yellow(), object);
14961513
}
14971514
// All other entries will be in the `errors` list.
14981515
}
14991516

15001517
// Print a summary of all errors at the bottom.
15011518
let mut errored = vec![];
15021519
for (checksum, error) in errors {
1503-
let dif = difs_by_checksum
1520+
let object = objects_by_checksum
15041521
.get(&checksum)
15051522
.ok_or_else(|| format_err!("Server returned unexpected checksum"))?;
1506-
errored.push((dif, error));
1523+
errored.push((object, error));
15071524
}
1508-
errored.sort_by_key(|x| x.0.object().file_name());
1525+
errored.sort_by_key(|x| x.0.name());
15091526

15101527
let has_errors = !errored.is_empty();
1511-
for (dif, error) in errored {
1528+
for (object, error) in errored {
15121529
let fallback = match error.state {
15131530
ChunkedFileState::Assembling => Some("The file is still processing and not ready yet"),
15141531
ChunkedFileState::NotFound => Some("The file could not be saved"),
15151532
_ => Some("An unknown error occurred"),
15161533
};
15171534

1518-
println!(" {:>7} {}", style("ERROR").red(), dif.object().file_name());
1535+
println!(" {:>7} {}", style("ERROR").red(), object.name());
15191536
render_detail(&error.detail, fallback);
15201537
}
15211538

@@ -1565,7 +1582,7 @@ fn upload_difs_chunked(
15651582
// Only if DIFs were missing, poll until assembling is complete
15661583
let (missing_difs, _) = missing_info;
15671584
if !missing_difs.is_empty() {
1568-
poll_dif_assemble(&missing_difs, options)
1585+
poll_assemble(&missing_difs, options)
15691586
} else {
15701587
println!(
15711588
"{} Nothing to upload, all files are on the server",

0 commit comments

Comments
 (0)