Refactor: extract lib.rs into focused sub-modules, add --output-dir CLI option

- Split monolithic src/lib.rs (~640 lines) into 7 sub-modules:
  types.rs, context.rs, user_data.rs, translate.rs, http.rs,
  csv_util.rs, test_utils.rs
- Add configurable --output-dir CLI option for CSV output files
- Implement atomic file writes (write-to-temp + rename) for all CSVs
- Change compute_car_counts() to return CarCounts directly (not Result)
- Add test-utils feature gate for shared test helpers
- Add HTTP mock tests with mockito (6 tests)
- Add proptest tests for compute_car_counts (3 property tests)
- Update integration tests to use shared test utilities
- Update documentation (API.md, ARCHITECTURE.md, DATA_STRUCTURES.md)
This commit is contained in:
Jan-Peter von Hunnius 2026-05-08 20:21:46 +02:00
parent d2c1418e5e
commit 67a79f190a
27 changed files with 1648 additions and 789 deletions

View file

@ -8,7 +8,14 @@ This document provides comprehensive API documentation for the Top Drives Record
```
src/
├── lib.rs # Shared library: types, utilities, error handling
├── lib.rs # Thin re-export module: declares sub-modules, re-exports public types
├── types.rs # Core types: AppError, Car, BestCarRecord, TripletKey
├── context.rs # Analysis state: AnalysisContext, CarCounts, compute_car_counts
├── user_data.rs # User data: MyCarsData, load_my_cars_data
├── translate.rs # Translation: translate_track_name, translate_track_type
├── http.rs # HTTP: get_file (async download with retry)
├── csv_util.rs # CSV utilities: compare_cars, escape_csv_field
├── test_utils.rs # Test helpers: make_record, make_car
├── records.rs # Binary entry point: CLI definition and dispatch
├── commands/
│ ├── mod.rs # Command dispatch, run_analysis(), load_my_cars_or_warn()
@ -30,7 +37,7 @@ src/
## Shared Library (`src/lib.rs`)
Common types and utilities shared across the project.
Thin re-export module that declares 6 focused sub-modules and re-exports all public types for backward compatibility. External code can use `top_drives::Car` without knowing the internal module layout.
### Public Types
@ -176,7 +183,7 @@ pub enum AppError {
- Sorts by: RQ → Brand → Model name
#### `compute_car_counts(ctx: &AnalysisContext, car_list: Vec<Car>) -> Result<CarCounts, AppError>`
#### `compute_car_counts(ctx: &AnalysisContext, car_list: Vec<Car>) -> CarCounts`
**Aggregates per-car win counts from analysis context**
- Iterates all entries in the `DashMap`

View file

@ -8,17 +8,19 @@ The Top Drives Records Analyzer is a Rust CLI tool for analyzing car performance
### 1. Shared Library (`src/lib.rs`)
**Common types and utilities** shared across the project.
**Thin re-export module** that declares 6 focused sub-modules and re-exports all public types for backward compatibility. External code can use `top_drives::Car` without knowing the internal module layout.
#### Key Responsibilities
- **Data Types**: Defines `Car`, `BestCarRecord`, `AnalysisContext`, `CarCounts`, `MyCarsData`, `AppError`
- **Track Name Translation**: Converts track codes to human-readable names via `translate_track_name()`
- **Track Type Translation**: Converts condition codes to surface descriptions via `translate_track_type()`
- **File Download**: Async file download utility with retry logic via `get_file()`
- **User Data Loading**: Parses `my_cars.json` via `load_my_cars_data()`
- **Car Comparison**: Sorting comparator via `compare_cars()`
- **Count Aggregation**: Per-car win count computation via `compute_car_counts()`
- **CSV Escaping**: Safe CSV field formatting via `escape_csv_field()`
#### Sub-modules
| Module | File | Key Exports |
|--------|------|-------------|
| `types` | `src/types.rs` | `AppError`, `BestCarRecord`, `Car`, `TripletKey` |
| `context` | `src/context.rs` | `AnalysisContext`, `CarCounts`, `compute_car_counts` |
| `user_data` | `src/user_data.rs` | `MyCarsData`, `load_my_cars_data` |
| `translate` | `src/translate.rs` | `translate_track_name`, `translate_track_type` |
| `http` | `src/http.rs` | `get_file` |
| `csv_util` | `src/csv_util.rs` | `compare_cars`, `escape_csv_field` |
| `test_utils` | `src/test_utils.rs` | `make_record`, `make_car` (test helpers) |
#### Error Handling
All public functions return `Result<T, AppError>` where `AppError` is a unified error type:
@ -42,6 +44,7 @@ All public functions return `Result<T, AppError>` where `AppError` is a unified
- `--cars-db` — Path to car database file (default: `cars_repo.json`)
- `--times-dir` — Directory for per-car timing JSON files (default: `times`)
- `--tracks-db` — Path to tracks database file (default: `tracks_repo.json`)
- `--output-dir` — Directory for output CSV files (default: `.`)
### 3. Commands Module (`src/commands/`)

View file

@ -199,7 +199,7 @@ This document describes the JSON data structures used by the Top Drives Records
| *value* | String | Human-readable track name (e.g., `"Laguna Seca"`) |
**Usage in Application**:
- Loaded by `translate_track_name()` in `src/lib.rs`
- Loaded by `translate_track_name()` in `src/translate.rs`
- Compiled into the binary at build time
- Fallback: Returns original track code if no mapping found