# API Documentation ## Overview This document provides comprehensive API documentation for the Top Drives Records Analyzer, including all public functions, data structures, and their usage patterns. ## Core Modules ### Records Module (`src/records.rs`) Primary analysis engine for processing JSON-based timing data. #### Public Functions ##### `main()` **Entry point for the records analyzer** ```rust #[tokio::main] async fn main() ``` **Purpose**: Command-line interface and operation dispatcher **Arguments**: Command line arguments - `args[1]`: Command (`fetch`, `best`, `missing`, `trash`, `details`, `track`) **Commands**: - `fetch`: Download all data files - `best`: Show best owned cars - `missing`: Show best unowned cars - `trash`: Show removable cars - `details`: Export all timing data - `track`: Track-specific analysis **Example**: ```bash cargo run --bin records -- best ``` ##### `print_best_cars(filter_out_owned: bool)` **Displays ranked list of best performing cars** ```rust fn print_best_cars(filter_out_owned: bool) ``` **Purpose**: Aggregates performance data across all tracks and conditions **Arguments**: - `filter_out_owned`: If true, excludes owned cars from output **Output Format**: ```csv RQ,Brand,Model,Year,Count 85,McLaren,F1,1993,15 82,Ferrari,250 GTO,1962,12 ``` **Algorithm**: 1. Count occurrences of each car across all track/RQ/condition combinations 2. Sort by RQ level, then by car identifier 3. Apply ownership filter if requested ##### `print_best_times()` **Exports comprehensive timing data for all combinations** ```rust fn print_best_times() ``` **Purpose**: Detailed performance export for external analysis **Output Format**: ```csv RQ,TrackID,Condition,CarRQ,Brand,Model,Year,Config,Time 85,laguna,Dry,85,McLaren,F1,1993,233,112.45 ``` **Data Volume**: Large output file with all track/condition/RQ combinations ##### `print_best_car(track: &String, condition: &String, rq: &String)` **Finds best car for specific track conditions** ```rust fn print_best_car(track: &String, condition: &String, rq: &String) ``` **Purpose**: Targeted analysis for specific racing scenarios **Arguments**: - `track`: Track identifier (e.g., "laguna", "monaco") - `condition`: Surface condition (e.g., "Dry", "Wet") - `rq`: RQ level limit **Example**: ```rust print_best_car(&"laguna".to_string(), &"Dry".to_string(), &"85".to_string()); ``` ##### `print_trash()` **Identifies cars safe for removal from collection** ```rust fn print_trash() ``` **Purpose**: Collection optimization recommendations **Safety Criteria**: - Car not among best performers on any track - RQ level below 80 (preserves high-end cars) - Not a prize car (may have collection value) **Output Format**: ```csv RQ,Brand,Model,Year 45,Toyota,Corolla,1995 ``` ##### `parse_car_times(car: Car)` **Processes timing data for a single car** ```rust async fn parse_car_times(car: Car) ``` **Purpose**: Core parsing logic for individual car performance data **Process Flow**: 1. Load car's JSON timing file 2. Parse each configuration (111, 233, 323, etc.) 3. Extract timing data for each track/condition 4. Apply quality filters (downvotes, time validation) 5. Update global best cars cache **Quality Filters**: - Minimum time: 1.2 seconds - No downvotes from community - Special handling for Test Bowl track ##### `parse_all_times()` **Orchestrates concurrent processing of all cars** ```rust async fn parse_all_times() ``` **Purpose**: Coordinates parallel processing of car timing files **Concurrency**: One async task per car file **Synchronization**: Waits for all tasks to complete ##### `update_best_car(track_id: &str, car_rq: u8, surface: &str, new_record: BestCarRecord)` **Updates global best cars database with new performance data** ```rust fn update_best_car(track_id: &str, car_rq: u8, surface: &str, new_record: BestCarRecord) ``` **Purpose**: Implements core best-car selection algorithm **RQ Range Analysis**: - Tests car from base RQ up to maximum (115) - Compares against existing best times - Updates records for improved performance **Logic**: 1. For each RQ level from car_rq to 115: 2. If new time is better → replace record 3. If new time ties → add to list (if not duplicate) 4. If new time is worse → ignore ##### `get_car_list() -> Vec` **Loads complete car database from repository file** ```rust fn get_car_list() -> Vec ``` **Purpose**: Provides access to all known cars in the database **Source**: `cars_repo.json` file **Returns**: Vector of all cars with complete metadata ##### `get_my_car_list() -> Vec` **Loads user's car collection from game export** ```rust fn get_my_car_list() -> Vec ``` **Purpose**: Identifies which cars the user owns **Source**: `my_cars.json` game export **Filter**: Only `locked: true` cards **Returns**: Vector of owned car GUIDs ##### `fetch_times()` **Downloads timing files for all cars with rate limiting** ```rust async fn fetch_times() ``` **Purpose**: Batch download of car timing data **Rate Limiting**: 20 concurrent downloads maximum **Progress**: Shows download progress for each file ##### `fetch_car(rid: String)` **Downloads timing data for single car** ```rust async fn fetch_car(rid: String) ``` **Purpose**: Individual car data fetching **URL Format**: `https://api.topdrivesrecords.com/car/{rid}` **Storage**: `times/{rid}.json` ##### `get_cars_file()` **Downloads main car database** ```rust async fn get_cars_file() ``` **Purpose**: Updates car metadata database **Source**: GitHub repository cars database **Destination**: `cars_repo.json` ##### `get_tracks_file()` **Downloads track definitions** ```rust async fn get_tracks_file() ``` **Purpose**: Updates track name mappings **Source**: GitHub repository tracks database **Destination**: `tracks_repo.json` ##### `get_file(file_url: &str, local_file_path: &str)` **Generic file download utility** ```rust async fn get_file(file_url: &str, local_file_path: &str) ``` **Purpose**: Downloads files from remote URLs **Features**: - Automatic existing file removal - Error handling with graceful failure - Progress indication through errors ##### `translate_track_name(track_code: &str) -> &str` **Converts track codes to human-readable names** ```rust fn translate_track_name(track_code: &str) -> &str ``` **Purpose**: User-friendly track name display **Coverage**: 200+ track mappings **Fallback**: Returns original code if not found ##### `translate_track_type(track_code: &str) -> &str` **Converts condition codes to surface descriptions** ```rust fn translate_track_type(track_code: &str) -> &str ``` **Purpose**: Human-readable surface condition names **Mappings**: - `"00"` → `"Dry"` - `"01"` → `"Wet"` - `"10"` → `"Dirt"` - `"11"` → `"Dirt Wet"` ##### `split_prefix_postfix<'a>(input: &'a str, delimiter: &'a str) -> Option<(&'a str, &'a str)>` **String splitting utility for track ID parsing** ```rust fn split_prefix_postfix<'a>(input: &'a str, delimiter: &'a str) -> Option<(&'a str, &'a str)> ``` **Purpose**: Parse track IDs with condition suffixes **Example**: ```rust split_prefix_postfix("laguna_a00", "_a") // Some(("laguna", "00")) ``` ### Club Module (`src/club.rs`) Alternative data source using web scraping from topdrives.club. #### Public Functions ##### `main()` **Entry point for club scraper** ```rust #[tokio::main] async fn main() ``` **Purpose**: Web scraping interface for live data **Arguments**: - Command line arguments for RQ and track filtering - `-d` flag for detailed output ##### `get_page(url: &str) -> String` **Fetches HTML content from URLs** ```rust async fn get_page(url: &str) -> String ``` **Purpose**: Downloads web pages for scraping **Security**: Accepts invalid SSL certificates for compatibility ##### `parse_best_car(text: String) -> Car` **Extracts car data from HTML content** ```rust fn parse_best_car(text: String) -> Car ``` **Purpose**: Parses HTML tables to extract car information **CSS Selectors**: - `.carList__item-manufacturer`: Car brand - `.carList__item-model`: Car model - `.carList__item-year`: Model year - `.carList__item-level`: Class and RQ (complex parsing) - `.carList__item-upgrade`: Upgrade configuration ##### `parse_tracks(file_name: &str) -> HashMap` **Loads track definitions from file** ```rust fn parse_tracks(file_name: &str) -> HashMap ``` **Purpose**: Creates track ID to name mappings **Format**: Text file with `ID NAME` format per line ##### `get_best_car(track: u16, track_name: String, max_level: u16, detailed: bool) -> String` **Scrapes best car data for specific track** ```rust async fn get_best_car(track: u16, track_name: String, max_level: u16, detailed: bool) -> String ``` **Purpose**: Fetches and parses best car from topdrives.club **API Integration**: - Constructs topdrives.club API URLs - Parses HTML response tables - Formats output based on detail level ##### `parse_argument(args: &Vec, index: usize, min: u16, max: u16) -> u16` **Validates command line arguments** ```rust fn parse_argument(args: &Vec, index: usize, min: u16, max: u16) -> u16 ``` **Purpose**: Input validation with range checking **Panics**: On invalid values with descriptive messages ## Data Structures ### Records Module Data Types #### `Card` **User's car collection entry** ```rust struct Card { cardId: String, // Unique card identifier locked: bool, // Ownership status } ``` #### `Car` **Car metadata from database** ```rust struct Car { rid: String, // Repository ID brand: String, // Manufacturer only_name: String, // Model name year: u16, // Model year rq: u8, // Rarity level prize: bool, // Prize car status guid: String, // Game GUID } ``` #### `BestCarRecord` **Performance record for best cars** ```rust struct BestCarRecord { car_rid: String, // Car identifier brand: String, // Manufacturer only_name: String, // Model name year: u16, // Year rq: u8, // RQ level config: String, // Tune configuration time: f64, // Track time owned: bool, // User ownership guid: String, // Game identifier } ``` #### `TripletKey` **Composite key for track conditions** ```rust type TripletKey = (String, u8, String); // Track ID RQ Level Surface Condition ``` ### Club Module Data Types #### `Car` **Scraped car data from website** ```rust struct Car { class: String, // Class letter (S, A, B, etc.) rq: u8, // Rarity level manufacturer: String, // Brand name model: String, // Model name year: u16, // Model year upgrade: String, // Upgrade config } ``` ## Global State ### `BEST_CARS` Cache **Thread-safe global performance database** ```rust static BEST_CARS: Lazy>>> ``` **Initialization**: One-time setup with `once_cell::Lazy` **Thread Safety**: Protected by `Mutex` for concurrent access **Structure**: HashMap with composite keys for efficient lookups ## Error Handling ### Network Errors - **HTTP Failures**: Logged but don't crash application - **Invalid JSON**: Graceful fallback to defaults - **Missing Files**: Clear error messages for user ### Parse Errors - **Malformed Data**: Skip invalid entries - **Type Conversion**: Use safe defaults - **Missing Fields**: Provide sensible fallbacks ### User Input Errors - **Invalid Commands**: Clear usage instructions - **Missing Arguments**: Descriptive error messages - **Out of Range**: Validation with helpful feedback ## Usage Examples ### Basic Analysis Workflow ```rust // 1. Load user's car collection let my_cars = get_my_car_list(); // 2. Process all car timing data parse_all_times().await; // 3. Generate best cars report print_best_cars(false); // 4. Find collection optimization opportunities print_trash(); ``` ### Track-Specific Analysis ```rust // Analyze specific track conditions let track = "laguna".to_string(); let condition = "Dry".to_string(); let rq = "85".to_string(); print_best_car(&track, &condition, &rq); ``` ### Data Fetching ```rust // Download fresh data get_cars_file().await; get_tracks_file().await; fetch_times().await; ``` ## Performance Characteristics ### Time Complexity - **Parsing**: O(n) where n = number of cars × tracks - **Best Car Selection**: O(1) HashMap operations - **Sorting**: O(n log n) for output ordering ### Memory Usage - **Peak**: ~200-300MB during full analysis - **Baseline**: ~50MB application overhead - **Per Car**: ~1-2KB metadata + timing data ### Concurrency - **Downloads**: 20 concurrent connections max - **Processing**: One task per car file - **Thread Safety**: Mutex-protected shared state ## Extension Points ### Adding New Commands 1. Add command parsing in `main()` 2. Implement analysis function 3. Update help documentation ### Adding New Data Sources 1. Implement new module (similar to `club.rs`) 2. Add data source selection logic 3. Update configuration system ### Custom Analysis Types 1. Create new output formatting functions 2. Add aggregation algorithms 3. Extend data structures as needed ## Testing ### Unit Tests ```rust #[cfg(test)] mod tests { use super::*; #[tokio::test] async fn test_parse_car_times() { // Test implementation } } ``` ### Integration Tests - Full workflow testing - File I/O validation - Network request mocking ### Benchmarking - Parse performance measurement - Memory usage profiling - Concurrent operation testing ## Security Considerations ### Network Security - HTTPS-only external requests - Certificate validation (with fallback) - No sensitive data transmission ### File System Security - Read-only access to game files - No modification of user data - Safe file path handling ### Input Validation - Command injection prevention - Path traversal protection - Input sanitization ## Troubleshooting API Issues ### Common Problems **"Function not found"** - Check module imports - Verify function signatures - Ensure proper visibility **"Type mismatch"** - Review struct field types - Check function signatures - Verify generic parameters **"Deadlock"** - Avoid nested Mutex locks - Check lock ordering - Use timeout where possible ### Debug Strategies **Logging**: ```rust println!("Processing car: {}", car.rid); eprintln!("Error: {}", error); ``` **Tracing**: ```rust // Add at function entry let _span = tracing::span!(Level::INFO, "function_name"); let _enter = _span.enter(); ``` **Profiling**: ```bash cargo flamegraph --bin records -- best ``` ## Migration Guide ### Version Compatibility - **Current**: 0.2.0 API stable - **Previous**: 0.1.0 fully compatible - **Future**: Semantic versioning maintained ### Breaking Changes - None currently planned - Advance notice provided for API changes - Deprecation warnings for removed features --- **API Version**: 0.2.0 **Last Updated**: 2024-12-XX **Compatibility**: Rust 1.70.0+