Application Entry Point & Request Lifecycle
Entry Point — main.rs
The binary entry point performs two steps and nothing else:
- Parse the command line into a
Clistruct (viaclap). - Call
app::run(&cli)and handle any returnedAppErrorby logging it and exiting with a non-zero code.
// Conceptual outline of main.rs
fn main() {
let cli = Cli::parse();
if let Err(e) = app::run(&cli) {
eprintln!("Error: {e}");
std::process::exit(1);
}
}
app::run — The Lifecycle Coordinator
app::run drives the full Parse → Validate → Execute sequence:
Step 1 — Build RuntimeConfig
#![allow(unused)]
fn main() {
let config = RuntimeConfig::try_from(&cli)?;
}
RuntimeConfig::try_from validates every argument (see Configuration) and fails fast with a descriptive AppError on any violation.
Step 2 — Validate the Input File
validate_input_file performs filesystem-level checks before any network call is made:
- The input path must exist and be a regular file.
- The file size must not exceed
MAX_FILE_SIZE_BYTES(1 MB). - The output extension must match the input extension — e.g., you cannot translate a
.csvinto a.docx. - Parent directories for the output path are created if they do not exist.
Step 3 — Dispatch to Format Handler
#![allow(unused)]
fn main() {
formats::translate_file(&config).await?;
}
translate_file inspects the input extension and routes to the appropriate handler:
| Extension | Handler |
|---|---|
.csv | formats::csv_tsv::translate |
.tsv | formats::csv_tsv::translate |
.docx | formats::docx::translate |
.pdf | formats::pdf::translate (requires pdf feature) |
An unrecognised extension returns AppError::UnsupportedFormat.
Initialization Sequence (Diagram)
main()
│
├─ Cli::parse() # clap parses argv
│
└─ app::run(&cli)
│
├─ RuntimeConfig::try_from(&cli) # validation
│ └─ AppError on failure
│
├─ validate_input_file() # filesystem checks
│ └─ AppError on failure
│
└─ formats::translate_file(&config) # dispatch
├─ TmtClient::new()
├─ TranslationService::new()
└─ <format handler>::translate()