1. What speech recognition writes for parse_config and main.rs
Speech-to-text has no idea a Cargo workspace exists. Ask an agent to “make send with retry respect the backoff in http client dot rs” and the transcript is a sentence of ordinary words: no underscores, no extension, and the rs may come out as two separate letters. Crate names fare worse, because many are also English words or close to them, so tokio can arrive as Tokyo and serde as “sir day”.
The compiler is strict about names, and so is a reviewer. An agent can usually recover from loose words, but each guess costs a search through the workspace, and a commit message that says “parse config” instead of parse_config is harder to find with grep later.
2. RFC 430 and the API Guidelines, read aloud
RFC 430 sets the conventions most Rust code follows. Crates, modules, functions, methods and local variables are snake_case; types, traits and enum variants are UpperCamelCase; static and constant variables are SCREAMING_SNAKE_CASE; type parameters are a concise UpperCamelCase name, usually a single letter like T; lifetimes are short and lowercase, like 'a. General constructors are new or with_more_details, and conversion constructors are from_some_other_type. The Rust API Guidelines repeat the table, list macros as snake_case!, and ask that crate names not use -rs or -rust as a suffix or prefix.
Acronyms get their own rule. In UpperCamelCase an acronym counts as one word, so it is Uuid rather than UUID; in snake_case it is lowercased, as in is_xid_start. A single letter should not be a word of its own unless it is the last one, which is why the standard library has btree_map rather than b_tree_map, but PI_2 rather than PI2.
- HttpClient is said “HTTP client”; under RFC 430 the acronym is one word, and the project’s spelling sets the capitals.
- MAX_IN_FLIGHT is said “max in flight”; the screaming case is silent.
- btree_map_len can be said “B tree map len” or “btree map len”, since only letters are compared.
- T, 'a and the ? operator are syntax, not names, and stay out of dictation.
3. Spoken to typed in a Cargo workspace
Applied to a small rate-limiting crate with src/lib.rs, src/http_client.rs, src/token_bucket.rs, a build.rs, an integration test and a workspace member in crates/invoice-core, IraVoice’s matching rules give these results in a recognized app on a Mac or Windows PC:
- “send with retry ignores the backoff” → send_with_retry ignores the backoff
- “rate limiter” → RateLimiter; “parse error” → ParseError
- “max in flight” → MAX_IN_FLIGHT; “default timeout MS” → DEFAULT_TIMEOUT_MS
- “is xid start” → is_xid_start; “B tree map len” → btree_map_len
- “try acquire” → try_acquire, a method declared with fn inside an impl block
- “cargo dot toml” → Cargo.toml; “cargo dot lock” → Cargo.lock
- “main dot R S” → main.rs; “lib dot rs” → lib.rs; “build dot rs” → build.rs
- “integration test rs” → integration_test.rs
4. Modules, crates and the hyphen-to-underscore switch
Methods are declared with fn inside impl blocks, so they are collected like free functions, and let bindings with longer names, such as retry_budget, count too. Struct fields written as refill_rate: u32 are not declarations IraVoice reads, and names defined with macro_rules! stayed as words in the sample project.
Rust projects often name a module after the type it holds: TokenBucket in token_bucket.rs, HttpClient in http_client.rs. Spoken, the pair is the same words, and IraVoice can type only one name for one phrase; in this layout it types the module, so “token bucket” arrives as token_bucket. That is usually enough for an agent to find the type. In a review comment where the type matters, fix the capitals by hand.
Crates add a second split. Cargo’s documentation says a library target’s name defaults to the package name with any dashes replaced with underscores, while the default binary in src/main.rs keeps the package name as it is. A workspace member in crates/invoice-core is therefore invoice-core in Cargo.toml and in cargo -p, and invoice_core in a use path. IraVoice sees the folder, so “invoice core” types invoice-core: right for Cargo commands, and worth changing to the underscore form when you write about a use path.
File names that mix separators behave as in other languages. “integration test rs” gives integration_test.rs, while “integration test dot rs” mixes two spellings and leaves “dot rs” as words. Cargo’s package layout puts kebab-case files in src/bin, benches and tests, such as named-executable.rs; say those as “named executable rs”.
5. tokio, serde and other crates the model mishears
Dependencies are not part of your repository’s own files, and IraVoice skips the target folder, so crate names from crates.io are not in its list unless your code declares something with the same name. Teach the ones you use. Dictate, press ⌃⌥⇧F on a Mac or Ctrl+Alt+Shift+F on Windows and Linux, correct “Tokyo” to tokio or “sir day” to serde, and press Enter. The corrected text is copied to paste back, and only the word pair is kept.
Choose lessons with care. A learned fix applies in every app, so teaching Tokyo → tokio changes the city in your email as well; review or forget lessons under Advanced → Learn from my fixes. For fixed text, use a Replacement: a phrase that types your crate’s repository URL, or “clippy note” for a review comment you paste often.
6. RustRover, Zed, terminals and Linux
On a Mac, names are spelled in RustRover and the other JetBrains IDEs, Zed, VS Code, Cursor, Windsurf and Sublime Text, in Terminal, iTerm2, Ghostty, Warp, kitty, Alacritty, WezTerm and Hyper, and in the Claude and Codex desktop apps. On Windows the recognized apps include VS Code, Cursor, Windsurf, Zed, Windows Terminal, PowerShell, cmd, WezTerm, Alacritty and four JetBrains IDEs (IntelliJ IDEA, PyCharm, WebStorm and Rider); RustRover is not among them, so it gets plain dictation there.
Plenty of Rust work happens on Linux. IraVoice’s Linux beta (an AppImage for any 64-bit distribution from 2022 on, or a .deb or .rpm) dictates into your terminal or editor, but it cannot detect the focused app there, so code names are not spelled. Over SSH, names come only from a Git project on the local computer.
It is not a way to write Rust by voice: no ::, ->, &mut, generics, lifetimes or semicolons. For that, Talon’s community commands include formatters such as snake, hammer, constant and packed, the last of which joins words with double colons, as in one::two::three. Claude Code’s /voice suits short prompts if you sign in with Claude.ai and accept transcription on Anthropic’s servers. macOS Dictation and Win+H are free for prose.
IraVoice recognizes speech on the computer with NVIDIA Parakeet, after a one-time model download of about 700 MB. Hold Right Command on a Mac or Right Ctrl on Windows (Ctrl+Space on Linux) to dictate. It costs $79 once for one computer, $109 for two, or $149 for three, after a 3-day free trial.