docs: update documentation for normalized config and improve command
- Add improve command to all command tables and usage sections - Add normalized_config field to BestCarRecord struct documentation - Update CarCounts.by_rid type from String to (String, String) - Update CarCounts.guid_to_rid type to HashMap<String, HashSet<(String, String)>> - Add owned_configs field to MyCarsData and CarCounts docs - Add normalize_to_final_build() to API docs - Update CSV format examples to include FinalBuild column - Update my_cars.json structure with engineMajor/weightMajor/chassisMajor - Update timing file example with v2c_ version prefix - Add version prefix stripping to data transformation docs - Update CHANGELOG.md with Unreleased section - Fix compare_records description to include normalized config sorting
This commit is contained in:
parent
bf21d3d1f6
commit
2b0602d564
6 changed files with 204 additions and 84 deletions
63
docs/API.md
63
docs/API.md
|
|
@ -25,6 +25,7 @@ src/
|
|||
│ ├── wishlist.rs # Wishlist command: wishlist.csv, add.csv, remove.csv
|
||||
│ ├── details.rs # Details command: details.csv
|
||||
│ ├── track.rs # Track command: stdout query
|
||||
│ ├── improve.rs # Improve command: improve.csv (owned cars not at final build)
|
||||
│ └── all.rs # All command: generates all output files
|
||||
├── parsing/
|
||||
│ ├── mod.rs # Core parsing: parse_car_times, update_best_car, parse_all_times
|
||||
|
|
@ -69,16 +70,17 @@ pub struct Car {
|
|||
```rust
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BestCarRecord {
|
||||
pub car_rid: String, // Car identifier
|
||||
pub brand: String, // Manufacturer
|
||||
pub only_name: String, // Model name
|
||||
pub year: u16, // Year
|
||||
pub rq: u8, // RQ level
|
||||
pub config: String, // Tune config (111, 233, etc.)
|
||||
pub time: f64, // Track time in seconds
|
||||
pub owned: bool, // User ownership status
|
||||
pub prize: bool, // Prize car status
|
||||
pub guid: String, // Game identifier
|
||||
pub car_rid: String, // Car identifier
|
||||
pub brand: String, // Manufacturer
|
||||
pub only_name: String, // Model name
|
||||
pub year: u16, // Year
|
||||
pub rq: u8, // RQ level
|
||||
pub config: String, // Original tune config from JSON (111, 221, 233, etc.)
|
||||
pub normalized_config: String, // Normalized final build (323, 233, or 332)
|
||||
pub time: f64, // Track time in seconds
|
||||
pub owned: bool, // User ownership status
|
||||
pub prize: bool, // Prize car status
|
||||
pub guid: String, // Game identifier
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -109,21 +111,25 @@ pub struct AnalysisContext {
|
|||
|
||||
```rust
|
||||
pub struct CarCounts {
|
||||
pub by_rid: HashMap<String, (BestCarRecord, usize)>,
|
||||
pub guid_to_rid: HashMap<String, String>,
|
||||
pub by_rid: HashMap<(String, String), (BestCarRecord, usize)>,
|
||||
pub guid_to_rid: HashMap<String, HashSet<(String, String)>>,
|
||||
pub car_map: HashMap<String, Car>,
|
||||
pub car_list: Vec<Car>,
|
||||
pub owned_configs: HashMap<String, String>,
|
||||
}
|
||||
```
|
||||
|
||||
**Key grouping**: `by_rid` is keyed by `(car_rid, normalized_config)` so different tune configs of the same car are tracked separately. `guid_to_rid` maps each GUID to all `(rid, config)` pairs it appears under.
|
||||
|
||||
#### `MyCarsData`
|
||||
**Parsed user data from `my_cars.json`**
|
||||
|
||||
```rust
|
||||
#[derive(Debug, Default)]
|
||||
pub struct MyCarsData {
|
||||
pub owned: HashSet<String>, // Owned car GUIDs
|
||||
pub wishlist: HashSet<String>, // Wishlist car GUIDs
|
||||
pub owned: HashSet<String>, // Owned car GUIDs
|
||||
pub wishlist: HashSet<String>, // Wishlist car GUIDs
|
||||
pub owned_configs: HashMap<String, String>, // GUID → actual tune config (e.g., "233")
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -183,11 +189,12 @@ pub enum AppError {
|
|||
|
||||
- Sorts by: RQ → Brand → Model name
|
||||
|
||||
#### `compute_car_counts(ctx: &AnalysisContext, car_list: Vec<Car>) -> CarCounts`
|
||||
#### `compute_car_counts(ctx: &AnalysisContext, car_list: Vec<Car>, owned_configs: HashMap<String, String>) -> CarCounts`
|
||||
**Aggregates per-car win counts from analysis context**
|
||||
|
||||
- Iterates all entries in the `DashMap`
|
||||
- Returns `CarCounts` with by_rid, guid_to_rid, car_map, and car_list
|
||||
- Groups by `(car_rid, normalized_config)` for per-config tracking
|
||||
- Returns `CarCounts` with by_rid, guid_to_rid, car_map, car_list, and owned_configs
|
||||
|
||||
#### `escape_csv_field(field: &str) -> String`
|
||||
**Escapes a field for safe CSV inclusion**
|
||||
|
|
@ -195,6 +202,14 @@ pub enum AppError {
|
|||
- Wraps in quotes if field contains comma, quote, newline, or carriage return
|
||||
- Doubles internal quotes per CSV spec
|
||||
|
||||
#### `normalize_to_final_build(config: &str) -> String`
|
||||
**Normalizes a tune configuration to the closest "final build"**
|
||||
|
||||
- The three final builds are `"323"`, `"233"`, and `"332"` (permutations of digits summing to 8)
|
||||
- For non-standard configs, repeatedly increments the smallest digit until sum reaches 8
|
||||
- Returns the original string unchanged if config cannot be parsed or sum already ≥ 8
|
||||
- Version prefixes (`v2c_`, `v1c_`) are stripped at parse time before reaching this function
|
||||
|
||||
---
|
||||
|
||||
## Records Binary (`src/records.rs`)
|
||||
|
|
@ -221,6 +236,7 @@ CLI entry point. Defines command-line arguments and dispatches to command handle
|
|||
| `all` | Generate all output files in a single pass | `--min-count N`, `--max-wishlist M` |
|
||||
| `details` | Generate `details.csv` with all timing data | None |
|
||||
| `track` | Show best car for specific track/condition/RQ | `<track> <condition> <rq>` |
|
||||
| `improve` | Generate `improve.csv` (owned cars not at final build) | None |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -309,7 +325,7 @@ Loads car database, parses all timing files concurrently, and computes car count
|
|||
#### `write_best_csv(counts)`, `write_very_best_csv(counts, min_count)`
|
||||
**Generate best car CSV files**
|
||||
|
||||
- Format: `RQ,Brand,Model,Year,Count`
|
||||
- Format: `RQ,Brand,Model,Year,FinalBuild,Count`
|
||||
- Fields are CSV-escaped
|
||||
|
||||
#### `write_trash_csv(counts, owned)`
|
||||
|
|
@ -323,7 +339,16 @@ Loads car database, parses all timing files concurrently, and computes car count
|
|||
|
||||
- Computes ideal wishlist once
|
||||
- Derives all three files from it
|
||||
- Format: `RQ,Brand,Model,Year,Count`
|
||||
- Format: `RQ,Brand,Model,Year,FinalBuild,Count`
|
||||
|
||||
#### `write_improve_csv(counts) -> Result<usize, AppError>`
|
||||
**Generate improve CSV file**
|
||||
|
||||
- Lists owned cars whose actual player config is not yet a final build (323/233/332)
|
||||
- Uses actual player config from `my_cars.json`, not timing data configs
|
||||
- Format: `RQ,Brand,Model,Year,Target,Count`
|
||||
- Sorted by track count descending (most impactful upgrades first)
|
||||
- Returns the number of cars written
|
||||
|
||||
#### `write_details_csv(ctx)`
|
||||
**Generate comprehensive timing data CSV**
|
||||
|
|
@ -347,4 +372,4 @@ Loads car database, parses all timing files concurrently, and computes car count
|
|||
#### `compare_records(a: &BestCarRecord, b: &BestCarRecord) -> std::cmp::Ordering`
|
||||
**Comparison for BestCarRecord sorting**
|
||||
|
||||
- Sorts by: RQ → Brand → Model name
|
||||
- Sorts by: RQ → Normalized Config → Brand → Model name
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue