Library no longer prints to stderr: - Replace every eprintln! with log::warn! (lib: user_data, http; bin: parsing, output, commands); initialize env_logger in main with a warn-level default so output is unchanged unless RUST_LOG is set - Warn on missing/non-numeric "t" time fields instead of silently coercing them to 0.0; suppress the per-car NotFound warning (most cars legitimately have no timing file), keep warnings for real I/O errors Ownership and clone cleanup: - CarCounts no longer duplicates the car database: drop the car_list field and build car_map by consuming car_list (each Car stored once); iterate car_map.values() where the list was previously used - run_analysis takes MyCarsData by value: owned moves into the parse Arc, owned_configs/copy_count move into CarCounts; only the three commands that need owned/wishlist afterwards retain their own copy - is_final_build checks the digits directly (no per-call String allocation) and treats malformed configs as non-final so they surface in improve.csv; owned_final_configs becomes a borrowed rid-to-configs map so the target-exclusion check allocates nothing - Normalize sum arithmetic to u8 in normalize_to_final_build Docs and structure: - Document the first-seen-wins tie-breaking in compute_ideal_wishlist and the non-final/non-best coverage gap in write_trash_csv - Extract compare_by_rq_config_brand_name shared by compare_records and the remove.csv sort; drop the unused _output_dir parameter from run_track; add a retry_delay helper de-duplicating the three HTTP backoff sites; rename the shadowed `entry` binding to config_data
68 lines
2.5 KiB
Rust
68 lines
2.5 KiB
Rust
//! Command dispatch and shared helpers.
|
|
//!
|
|
//! Provides the `run_analysis` orchestration function and `load_my_cars_or_warn`
|
|
//! helper used by all command handlers.
|
|
|
|
pub mod all;
|
|
pub mod best;
|
|
pub mod details;
|
|
pub mod fetch;
|
|
pub mod improve;
|
|
pub mod track;
|
|
pub mod trash;
|
|
pub mod wishlist;
|
|
|
|
use std::sync::Arc;
|
|
|
|
use top_drives::{
|
|
compute_car_counts, load_my_cars_data, AnalysisContext, AppError, CarCounts, MyCarsData,
|
|
};
|
|
|
|
use crate::parsing::parse_all_times;
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Helper: load my_cars.json with graceful degradation
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/// Loads user car data, printing a warning and returning empty data if the file is missing.
|
|
///
|
|
/// Only `MissingFile` errors are gracefully degraded — parse errors and other
|
|
/// failures are propagated to the caller, because running analysis with
|
|
/// silently-corrupted ownership data would produce misleading results.
|
|
pub fn load_my_cars_or_warn(path: &str) -> Result<MyCarsData, AppError> {
|
|
match load_my_cars_data(path) {
|
|
Ok(data) => Ok(data),
|
|
Err(AppError::MissingFile(msg)) => {
|
|
log::warn!("{msg}");
|
|
log::warn!("Analysis will run without ownership data.");
|
|
Ok(MyCarsData::default())
|
|
}
|
|
Err(e) => Err(e),
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Analysis orchestration
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/// Common analysis setup: parses all timing files and computes car counts.
|
|
///
|
|
/// Takes `my_data` by value: `owned` is shared with the parse tasks via `Arc`,
|
|
/// and `owned_configs`/`copy_count` are moved into [`CarCounts`]. Callers that
|
|
/// need `owned` or `wishlist` after analysis must retain their own copy before
|
|
/// calling this function.
|
|
///
|
|
/// Returns the analysis context (for stdout commands) and the aggregated car counts
|
|
/// (for CSV output commands).
|
|
pub async fn run_analysis(
|
|
my_data: MyCarsData,
|
|
cars_db_path: &str,
|
|
times_dir: &str,
|
|
) -> Result<(AnalysisContext, CarCounts), AppError> {
|
|
let ctx = AnalysisContext::new();
|
|
let MyCarsData { owned, wishlist: _, owned_configs, copy_count } = my_data;
|
|
let owned = Arc::new(owned);
|
|
let car_list = parse_all_times(owned, &ctx, cars_db_path, times_dir).await?;
|
|
let counts = compute_car_counts(&ctx, car_list, owned_configs, copy_count);
|
|
Ok((ctx, counts))
|
|
}
|