feat: add normalized config tracking and improve command

- Add normalize_to_final_build() to map tune configs to final builds (323/233/332)
- Add normalized_config field to BestCarRecord
- Change CarCounts.by_rid key from String to (String, String) for per-config tracking
- Change CarCounts.guid_to_rid to HashMap<String, HashSet<(String, String)>>
- Extract owned tune configs from my_cars.json (engineMajor/weightMajor/chassisMajor)
- Add improve command: owned cars not yet at final build, sorted by track count
- Strip version prefixes (v2c_/v1c_) from config keys at parse time
- Update dedup check in update_best_car to consider normalized_config
- Add atomic_write helper for safe CSV output
- Delete completed plans/code-review-v2.md
- Apply rustfmt formatting across codebase
This commit is contained in:
Jan-Peter von Hunnius 2026-05-11 16:23:04 +02:00
parent 67a79f190a
commit bf21d3d1f6
25 changed files with 735 additions and 759 deletions

View file

@ -7,16 +7,15 @@ 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::collections::HashSet;
use std::sync::Arc;
use top_drives::{
AppError, AnalysisContext, CarCounts, MyCarsData,
compute_car_counts, load_my_cars_data,
compute_car_counts, load_my_cars_data, AnalysisContext, AppError, CarCounts, MyCarsData,
};
use crate::parsing::parse_all_times;
@ -51,13 +50,14 @@ pub fn load_my_cars_or_warn(path: &str) -> Result<MyCarsData, AppError> {
/// Returns the analysis context (for stdout commands) and the aggregated car counts
/// (for CSV output commands). The car list is stored inside `CarCounts`.
pub async fn run_analysis(
owned: &HashSet<String>,
my_data: &MyCarsData,
cars_db_path: &str,
times_dir: &str,
) -> Result<(AnalysisContext, CarCounts), AppError> {
let ctx = AnalysisContext::new();
let owned = Arc::new(owned.clone());
let owned = Arc::new(my_data.owned.clone());
let car_list = parse_all_times(owned, &ctx, cars_db_path, times_dir).await?;
let counts = compute_car_counts(&ctx, car_list);
// Move only owned_configs; construct a new MyCarsData to transfer ownership.
let counts = compute_car_counts(&ctx, car_list, my_data.owned_configs.clone());
Ok((ctx, counts))
}