4
4
use std:: collections:: { BTreeMap , BTreeSet } ;
5
5
use std:: convert:: TryInto ;
6
6
use std:: ffi:: { OsStr , OsString } ;
7
- use std:: fmt:: { self , Display } ;
7
+ use std:: fmt:: { self , Display , Formatter } ;
8
8
use std:: fs:: { self , File } ;
9
9
use std:: io:: { BufReader , BufWriter , Read , Seek , Write } ;
10
10
use std:: iter:: IntoIterator ;
@@ -38,7 +38,7 @@ use crate::api::{
38
38
use crate :: config:: Config ;
39
39
use crate :: constants:: { DEFAULT_MAX_DIF_SIZE , DEFAULT_MAX_WAIT } ;
40
40
use crate :: utils:: chunks:: {
41
- upload_chunks, BatchedSliceExt , Chunk , Chunked , ItemSize , MissingObjectsInfo ,
41
+ upload_chunks, BatchedSliceExt , Chunk , Chunked , ItemSize , MissingObjectsInfo , Named ,
42
42
ASSEMBLE_POLL_INTERVAL ,
43
43
} ;
44
44
use crate :: utils:: dif:: ObjectDifFeatures ;
@@ -273,6 +273,44 @@ impl AsRef<[u8]> for DifMatch<'_> {
273
273
}
274
274
}
275
275
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
+
276
314
/// A tuple which can be collected into a mapping of checksums to
277
315
/// `ChunkedDifRequest`s. The collected mapping can be sent in a
278
316
/// request to the assemble endpoint.
@@ -1361,23 +1399,27 @@ fn render_detail(detail: &Option<String>, fallback: Option<&str>) {
1361
1399
///
1362
1400
/// This function assumes that all chunks have been uploaded successfully. If there are still
1363
1401
/// 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 > ] ,
1366
1404
options : & DifUpload ,
1367
- ) -> Result < ( Vec < DebugInfoFile > , bool ) > {
1405
+ ) -> Result < ( Vec < DebugInfoFile > , bool ) >
1406
+ where
1407
+ T : Display + Named ,
1408
+ Chunked < T > : IntoAssembleRequest ,
1409
+ {
1368
1410
let progress_style = ProgressStyle :: default_bar ( ) . template (
1369
1411
"{prefix:.dim} Processing files...\
1370
1412
\n {wide_bar} {pos}/{len}",
1371
1413
) ;
1372
1414
1373
1415
let api = Api :: current ( ) ;
1374
- let pb = ProgressBar :: new ( difs . len ( ) ) ;
1416
+ let pb = ProgressBar :: new ( chunked_objects . len ( ) ) ;
1375
1417
pb. set_style ( progress_style) ;
1376
1418
pb. set_prefix ( ">" ) ;
1377
1419
1378
1420
let assemble_start = Instant :: now ( ) ;
1379
1421
1380
- let request = difs
1422
+ let request = chunked_objects
1381
1423
. iter ( )
1382
1424
. map ( |d| d. assemble_request ( options. pdbs_allowed ) )
1383
1425
. collect ( ) ;
@@ -1413,7 +1455,7 @@ fn poll_dif_assemble(
1413
1455
. filter ( |& ( _, r) | r. state . is_pending ( ) )
1414
1456
. count ( ) ;
1415
1457
1416
- pb. set_position ( ( difs . len ( ) - pending) as u64 ) ;
1458
+ pb. set_position ( ( chunked_objects . len ( ) - pending) as u64 ) ;
1417
1459
1418
1460
if pending == 0 {
1419
1461
break response;
@@ -1444,7 +1486,8 @@ fn poll_dif_assemble(
1444
1486
. to_owned ( )
1445
1487
} ) ;
1446
1488
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 ( ) ;
1448
1491
1449
1492
for & ( checksum, ref success) in & successes {
1450
1493
// Silently skip all OK entries without a "dif" record since the server
@@ -1462,60 +1505,34 @@ fn poll_dif_assemble(
1462
1505
) ;
1463
1506
1464
1507
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) {
1466
1509
// If we skip waiting for the server to finish processing, there
1467
1510
// are pending entries. We only expect results that have been
1468
1511
// 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) ;
1496
1513
}
1497
1514
// All other entries will be in the `errors` list.
1498
1515
}
1499
1516
1500
1517
// Print a summary of all errors at the bottom.
1501
1518
let mut errored = vec ! [ ] ;
1502
1519
for ( checksum, error) in errors {
1503
- let dif = difs_by_checksum
1520
+ let object = objects_by_checksum
1504
1521
. get ( & checksum)
1505
1522
. ok_or_else ( || format_err ! ( "Server returned unexpected checksum" ) ) ?;
1506
- errored. push ( ( dif , error) ) ;
1523
+ errored. push ( ( object , error) ) ;
1507
1524
}
1508
- errored. sort_by_key ( |x| x. 0 . object ( ) . file_name ( ) ) ;
1525
+ errored. sort_by_key ( |x| x. 0 . name ( ) ) ;
1509
1526
1510
1527
let has_errors = !errored. is_empty ( ) ;
1511
- for ( dif , error) in errored {
1528
+ for ( object , error) in errored {
1512
1529
let fallback = match error. state {
1513
1530
ChunkedFileState :: Assembling => Some ( "The file is still processing and not ready yet" ) ,
1514
1531
ChunkedFileState :: NotFound => Some ( "The file could not be saved" ) ,
1515
1532
_ => Some ( "An unknown error occurred" ) ,
1516
1533
} ;
1517
1534
1518
- println ! ( " {:>7} {}" , style( "ERROR" ) . red( ) , dif . object( ) . file_name ( ) ) ;
1535
+ println ! ( " {:>7} {}" , style( "ERROR" ) . red( ) , object. name ( ) ) ;
1519
1536
render_detail ( & error. detail , fallback) ;
1520
1537
}
1521
1538
@@ -1565,7 +1582,7 @@ fn upload_difs_chunked(
1565
1582
// Only if DIFs were missing, poll until assembling is complete
1566
1583
let ( missing_difs, _) = missing_info;
1567
1584
if !missing_difs. is_empty ( ) {
1568
- poll_dif_assemble ( & missing_difs, options)
1585
+ poll_assemble ( & missing_difs, options)
1569
1586
} else {
1570
1587
println ! (
1571
1588
"{} Nothing to upload, all files are on the server" ,
0 commit comments