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:
parent
d2c1418e5e
commit
67a79f190a
27 changed files with 1648 additions and 789 deletions
91
src/types.rs
Normal file
91
src/types.rs
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
//! Core data types and error definitions.
|
||||
//!
|
||||
//! Contains the fundamental types shared across the entire application:
|
||||
//! car records, error types, and composite key definitions.
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Custom error type for the Top Drives application.
|
||||
///
|
||||
/// Provides a unified error handling strategy across all modules,
|
||||
/// replacing the mix of `Result<(), String>`, `std::io::Result`, and
|
||||
/// silent `eprintln!` + early return patterns.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AppError {
|
||||
/// An I/O error occurred (file not found, permission denied, etc.)
|
||||
#[error("I/O error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
/// A network error occurred during data fetching
|
||||
#[error("Network error: {0}")]
|
||||
Network(String),
|
||||
|
||||
/// A JSON parsing error in a specific file
|
||||
#[error("Parse error in {file}: {reason}")]
|
||||
Parse {
|
||||
/// The file that failed to parse
|
||||
file: String,
|
||||
/// The reason for the parse failure
|
||||
reason: String,
|
||||
},
|
||||
|
||||
/// A required data file is missing
|
||||
#[error("Missing data file: {0}")]
|
||||
MissingFile(String),
|
||||
|
||||
/// An internal runtime error (e.g., semaphore closed, task join failure)
|
||||
#[error("Internal error: {0}")]
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
/// Core car information structure containing basic car metadata.
|
||||
/// Used throughout the application to represent car entities.
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub struct Car {
|
||||
/// Unique car identifier used in the records database
|
||||
pub rid: String,
|
||||
/// Car manufacturer/brand name
|
||||
pub brand: String,
|
||||
/// Car model name (without brand)
|
||||
#[serde(rename = "onlyName")]
|
||||
pub only_name: String,
|
||||
/// Car model year
|
||||
pub year: u16,
|
||||
/// Rarity level (10-113, affects performance brackets)
|
||||
pub rq: u8,
|
||||
/// Whether this car is only available as a prize car
|
||||
#[serde(default)]
|
||||
pub prize: bool,
|
||||
/// Game-specific unique identifier for the car
|
||||
pub guid: String,
|
||||
}
|
||||
|
||||
/// Represents the best performing car record for a specific track, RQ, and condition.
|
||||
/// Contains all necessary information to compare car performance.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BestCarRecord {
|
||||
/// Car identifier from the records database
|
||||
pub car_rid: String,
|
||||
/// Car manufacturer/brand name
|
||||
pub brand: String,
|
||||
/// Car model name (without brand)
|
||||
pub only_name: String,
|
||||
/// Car model year
|
||||
pub year: u16,
|
||||
/// Rarity level of this specific car configuration
|
||||
pub rq: u8,
|
||||
/// Tune configuration string (e.g., "111", "233", "323")
|
||||
pub config: String,
|
||||
/// Track time in seconds (lower is better)
|
||||
pub time: f64,
|
||||
/// Whether the current user owns this car
|
||||
pub owned: bool,
|
||||
/// Whether this car is only available as a prize car
|
||||
pub prize: bool,
|
||||
/// Game-specific unique identifier for the car
|
||||
pub guid: String,
|
||||
}
|
||||
|
||||
/// Type alias for the composite key used to identify unique track conditions.
|
||||
/// Consists of: (Track ID, RQ Level, Surface Condition)
|
||||
pub type TripletKey = (String, u8, String);
|
||||
Loading…
Add table
Add a link
Reference in a new issue