VIEW THIS AS

Auto mode follows the Route Engine until you choose a viewpoint.

YOU ARE HERE

ROUTE CHECK

CONNECTED TO

WHAT NEXT

Use the canonical route for this room, or HELP if you are unsure.

Translate Like a Pro | 9540 — Rust bpaf Localization, Derive and Combinator Help, ParseFailure, Completion and Unicode QA

Rust bpaf localization is the practice of translating command-line help, derive doc comments, combinator descriptions, diagnostics and completion guidance while preserving the parser’s accepted flags and typed output. Developers searching for bpaf derive examples, Rust bpaf Parser combinators, OptionParser help, ParseFailure handling and multilingual CLI testing need to know which parts are executable syntax and which parts are natural-language explanations.

The bpaf crate offers both a derive API and a combinatoric API for describing command-line interfaces. These can generate help and usage information, validate inputs and support optional completion and documentation features. But parsing is not a general-purpose language-catalog service. If a product wants Spanish, Japanese or Arabic help, the application must plan text ownership, locale choice, output formatting and release verification instead of assuming that translating source comments will automatically translate every diagnostic.

This practical guide follows a fictional, read-only research-index inspector called indexpeek. It uses safe example inputs, not real personal files. First we separate syntax from explanation; then we look at Rust types, helper parsers, custom usage, failure outcomes, completion and documentation formats. Every chapter returns to the same reader question: can someone follow the localized instructions and obtain exactly the behavior promised by the compiled binary?

Quick start: a dependable bpaf translation policy

  • Inventory the parser tree built by derive attributes, combinators and their composition.
  • Freeze short flags, long flags, command names, accepted literal values and typed result meanings.
  • Translate complete prose in help and usage without accidentally editing the option grammar.
  • Check actual package version and feature flags before documenting optional APIs.
  • Use controlled Args and parser-result tests for both success and failure states.
  • Keep help, diagnostics, stdout, stderr and process status distinct.
  • Generate completion and documentation from the same parser model as the shipped binary.
  • Review CJK, Arabic, accents and terminal widths in real target builds.
  • Ask new readers to reproduce safe tasks directly from translated help.

Why bpaf’s two APIs matter to translators

With a derive-based interface, fields, types, attributes and doc comments are close together. That is convenient for maintainers but invites the dangerous assumption that any visible string is safe to translate. A field name may be a Rust implementation detail, an annotation may define an actual flag, and a doc comment may become help prose. The correct translation boundary follows behavior rather than file location.

With a combinatoric interface, small parsers are composed into a larger parser. The same program can combine named switches, typed arguments, positionals, alternatives, defaults and groups. A translated guide should explain the complete resulting command, not just a list of primitives. Otherwise a reader may know every individual option and still not know a valid combination.

Executable names, accepted option identifiers, serialized values, environment keys and exit statuses are not synonyms for their explanatory labels. Keep them stable unless the product intentionally offers alternate localized command aliases with full compatibility tests. The article is about communication and reliable localization, not a recommendation to change interface contracts invisibly.

Generated usage, command completion, manual pages and errors form a family of outputs that may be produced through different code paths. Translating one screenshot is insufficient. A rigorous review starts from a controlled argument vector, records the typed outcome and then checks every presentation channel. That discipline is especially valuable in projects that ship multiple binary targets.

Not every limitation can be solved with the same API call. Some wording is supplied by the application; other wording may come from the crate or a supporting terminal renderer. Test the supported version, avoid inventing configuration switches and document English-only diagnostic paths if the application cannot replace them safely.

Small conceptual derive example

use bpaf::Bpaf;

// Build with bpaf's derive feature enabled for the selected crate release.
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
struct Options {
    /// Print additional diagnostics.
    #[bpaf(long, short)]
    verbose: bool,
}

// The generated helper and parsing API depend on the selected bpaf version.
// Pin the crate version, then compile and inspect --help in your CI tests.
fn main() {
    let options = options().run();
    println!("{options:?}");
}

The sample is a teaching sketch. It describes one boolean option and makes no claim that a localization catalog has already been wired in. Doc comments are English here so the parser’s default help can be inspected first; real multilingual support needs an explicit application-level design and tests. Check the exact signatures and feature configuration using the versioned official bpaf documentation before copying code into a production binary.

Field investigations: why localized bpaf CLIs succeed or fail

1. Derive annotations versus prose

The observable problem is specific: A team edits the doc comment on a field and expects the flag name to change in the same way. This is not just a wording issue. The derive layer uses attributes and types to define parsing, while documentation comments can become human-readable help.

Keep parser annotations fixed and review comments as translation resources with explicit locale context. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Use the same argv before and after translating help and assert equal typed output. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

2. Combinator composition

Consider what the reader sees when a localized manual is used. Two small combinators produce a single option parser, but documentation describes them as separate commands. The reason is technical: bpaf composes parsers into a typed result; a description must reflect the resulting combined interface.

Draw the actual composed parser shape before translating each description or making an example. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Invoke every documented combination in a harmless test and compare the resulting structure. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

3. short and long names

A reliable investigation begins by reproducing this mismatch: An editor changes -v and –verbose to match abbreviations in another language. It becomes understandable when we recognize that The short and long naming primitives define executable tokens, not mere labels.

Translate the purpose of verbosity, leave option spellings unchanged and publish one tested command line. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Run both aliases and one unsupported localized alias and inspect parser outcomes. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

4. NamedArg switch

This case is easy to miss in an English-only review. Help translates a switch as though it requires a value, so the next positional token is mistaken for that value. Underneath the presentation, A switch represents a boolean presence decision rather than an argument-bearing option.

Explain that presence changes the value and use the same wording for absent and present states. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Test no flag, one flag and an explicitly unsupported value after the flag. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

5. NamedArg flag

The observable problem is specific: An option with two specified outcomes is described as an arbitrary free-form text field. This is not just a wording issue. A flag combinator can map presence and absence to chosen application values.

Name the two possible application states and keep their actual command-line triggers literal. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Compare the behavior under both states without assuming the internal enum is user-facing. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

6. NamedArg argument

Consider what the reader sees when a localized manual is used. A numeric limit appears translated as a choice of words, but the parser expects a numeric argument. The reason is technical: Named arguments are converted from input strings into application types and can fail during parsing.

Show one valid typed example and describe the type constraint in the reader’s language. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Supply an integer, a decimal string and an empty value to document the tested behavior. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

7. positional arguments

A reliable investigation begins by reproducing this mismatch: A translated usage example reverses the order of a file and an output format. It becomes understandable when we recognize that Positionals are consumed according to parser structure, not the perceived natural word order of a language.

Preserve order in copyable syntax and explain the role of each positional separately. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Use two visibly different fixture strings and assert which field receives each. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

8. multiple values

This case is easy to miss in an English-only review. A translator says a switch may be repeated when the parser only accepts one occurrence. Underneath the presentation, Repetition is a property of parser composition, not a universal CLI convention.

Specify exactly which tokens repeat and whether their order matters to the application. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Try one occurrence, a duplicate and several distinct safe values. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

9. optional values

The observable problem is specific: A guide treats a missing option and an option with an empty value as interchangeable. This is not just a wording issue. An optional parser changes the type of the resulting data and still distinguishes input grammar.

Explain which absence is allowed and whether empty text is a valid supplied argument. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Test omitted option, explicit empty string and valid text. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

10. fallback defaults

Consider what the reader sees when a localized manual is used. Localized help promises a default locale that differs from the value supplied by fallback. The reason is technical: Fallback logic is data-producing parser behavior and may be defined in code outside the visible description.

Keep the help’s default statement synchronized with the actual parser’s fallback and catalog selection. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Run with no locale flag and compare generated help with the stored typed value. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

11. env option source

A reliable investigation begins by reproducing this mismatch: A product supports values from environment variables, but the translated guide assumes CLI input always wins. It becomes understandable when we recognize that Environment-backed parsing adds an input source whose precedence must be determined by the actual implementation.

Document the observed precedence and do not claim a generic system-locale selection that was not coded. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Set a safe environment variable and then override it with an explicit option. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

12. help via doc comments

This case is easy to miss in an English-only review. A well-written English doc comment becomes awkward generated help in German after being concatenated with syntax. Underneath the presentation, Generated help derives prose from source annotations and renders it with parser metadata.

Translate complete descriptions rather than isolated nouns while retaining the surrounding option grammar. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Generate help under each locale and ask a reader to identify the argument required. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

13. help headings

The observable problem is specific: An English heading such as Options is assumed to be a translatable resource without inspecting the version. This is not just a wording issue. Some framework-generated headings or diagnostics may be library-controlled rather than provided by the app.

Verify which text can be overridden through supported APIs, and state unresolved native-language limitations. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Inspect the actual installed crate output rather than promising comprehensive localization. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

14. custom_usage

Consider what the reader sees when a localized manual is used. A team replaces a default usage pattern with an elegant sentence that omits a required argument. The reason is technical: Custom usage can override or reshape automatically generated syntax summaries.

Protect required tokens and order when customizing and review the resulting text as a runnable specification. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Compare custom usage with a fresh valid command invocation. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

15. usage grouping

A reliable investigation begins by reproducing this mismatch: Translated documentation merges unrelated option groups because their headings seem synonymous. It becomes understandable when we recognize that Group help can organize related parameters while the underlying parsers remain distinct.

Define group boundaries by function and user task, not by superficial lexical similarity. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Ask a new reader to locate each tested flag from the translated help. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

16. hide and hide_usage

This case is easy to miss in an English-only review. A sensitive debugging option disappears from the help screen and translators assume it was removed from the parser. Underneath the presentation, Visibility settings influence documentation presentation without necessarily changing accepted input.

Keep security and support policy separate from the existence of undocumented switches. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Test behavior and generated help independently without encouraging hidden flags as public interfaces. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

17. subcommands

The observable problem is specific: A page translates a subcommand name into prose but shows the translated name as a real executable token. This is not just a wording issue. Command alternatives and their names are part of the parser grammar.

Keep command tokens stable, while translating their action summaries and examples. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Invoke each subcommand exactly as documented and verify the selected branch. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

18. enum alternatives

Consider what the reader sees when a localized manual is used. One translated description implies several enum branches run together when the parser selects one alternative. The reason is technical: A derived enum can represent mutually exclusive command shapes rather than an ordered sequence.

Use explicit ‘choose one’ wording where the tested parser requires a single alternative. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Feed arguments for each branch separately and check for accidental cross-branch acceptance. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

19. adjacent groups

A reliable investigation begins by reproducing this mismatch: Two values must appear together, but a translation separates them in example syntax. It becomes understandable when we recognize that Adjacent parsing expresses a structural relationship between arguments.

Keep grouped tokens together in command examples and explain that relationship in plain language. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Try separated and adjacent token orders against safe fixtures. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

20. parser invariants

This case is easy to miss in an English-only review. Documentation claims a parser is valid because its help rendered, but the composed parser has an invalid structure. Underneath the presentation, bpaf exposes checks for some parser invariants in addition to runtime parsing.

Run available invariant checks in tests and treat their failures as structural defects, not translation issues. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Validate the composition before any localized screenshot review. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

21. run_inner

The observable problem is specific: A tutorial tests by launching the process only, hiding which Args were actually supplied. This is not just a wording issue. OptionParser::run_inner permits controlled parsing of custom argument collections for tests.

Use fixed argument vectors to make language regression tests reproducible without shell interpretation. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Compare successful and failing vectors and capture the precise parse outcome. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

22. ParseFailure

Consider what the reader sees when a localized manual is used. A translated exception summary conflates help display with an error and assigns both failure status. The reason is technical: ParseFailure models unsuccessful parse outcomes and exposes different result handling methods.

Inspect the actual outcome before choosing a localized error, exit status or display channel. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Request –help and an invalid option separately, then inspect their status and output. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

23. stdout versus stderr

A reliable investigation begins by reproducing this mismatch: A CI pipeline starts reading translated parse errors as structured output because all messages were printed together. It becomes understandable when we recognize that The command boundary and ParseFailure reporting control which stream communicates human diagnostics.

Keep machine-facing output separate from help and error prose according to the program’s documented contract. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Capture both streams and compare in every supported locale. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

24. Non-UTF-8 OS arguments

This case is easy to miss in an English-only review. A guide assumes every operating-system argument arrives as a valid Unicode text string. Underneath the presentation, Rust uses OS-specific argument representations, and a parser may impose conversion restrictions.

Document the tested platform limits and avoid promising arbitrary byte-preserving path acceptance. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Use harmless non-ASCII filenames and platform-specific fixtures where supported. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

25. Unicode filenames

The observable problem is specific: An example silently normalizes a path and later fails to open the originally named fixture. This is not just a wording issue. Unicode normalization, filesystem rules and parser conversion are separate behaviors.

Keep the supplied user path intact unless deliberate normalization is specified and tested. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Compare composed and decomposed accent fixtures on the release platform. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

26. Chinese column width

Consider what the reader sees when a localized manual is used. Help printed with Chinese descriptions wraps so a value placeholder looks connected to the wrong option. The reason is technical: Display width is not simply the number of UTF-8 bytes and styling can change wrapping.

Review real terminal output at constrained widths rather than trusting plain-text line counts. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Capture 60-column and 100-column help using the distributed binary. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

27. Arabic mixed direction

A reliable investigation begins by reproducing this mismatch: An Arabic help example mixes a Latin command, Unicode filename and punctuation in confusing visual order. It becomes understandable when we recognize that Bidirectional rendering can reorder how mixed-script text appears on screen without changing argv bytes.

Place literal commands on separate code lines and verify copyability with bilingual reviewers. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Paste a displayed command back into a test runner and compare its exact argv sequence. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

28. Color and accessibility

This case is easy to miss in an English-only review. A localized warning depends on red highlighting and loses its severity in monochrome terminal recordings. Underneath the presentation, Styling is a presentation layer and may be disabled by terminal capability or user preference.

Include descriptive severity words and preserve accessible plain text independently of color. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Turn off color and inspect the complete message, not just the colored screenshot. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

29. shell completion

The observable problem is specific: A completion candidate changes from stable command token to translated word and no longer invokes the program. This is not just a wording issue. Completion suggests executable names and argument values whose meanings may be machine-facing.

Localize annotations when supported but keep accepted candidates aligned to the parser and application. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Generate completion with the documented feature enabled and test candidates in a clean shell. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

30. complete_shell

Consider what the reader sees when a localized manual is used. A guide claims an interactive completion behavior works in all shells without checking supported integrations. The reason is technical: Completion API and shell-specific generation require version and feature alignment.

Name supported shells and installed feature flags rather than promising universal completion. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Exercise bash, zsh or other officially supported shells where available and record any gaps. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

31. completion of values

A reliable investigation begins by reproducing this mismatch: Human labels in a completion menu are mistaken for actual serialized argument values. It becomes understandable when we recognize that The suggested value and its friendly description can have separate roles.

Treat completions as user-interface hints while preserving values recognized by the parser. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Select a completed item and confirm the resulting argv is valid. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

32. markdown docs

This case is easy to miss in an English-only review. A generated Markdown reference is translated but no longer matches the actual –help output. Underneath the presentation, Documentation output can be derived from parser metadata and customized separately.

Use the same tested parser definition to produce both and review their differences intentionally. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Regenerate Markdown after changing translations and compare command signatures. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

33. manpage output

The observable problem is specific: A localized manual page documents options that the packaged build does not expose. This is not just a wording issue. Generated manpages can drift if they are not rebuilt from the shipped command model.

Build manuals from the same version and keep example commands executable. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Install the package and verify the manpage against its –help listing. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

34. HTML documentation

Consider what the reader sees when a localized manual is used. A doc renderer escapes a less-than placeholder incorrectly and readers copy markup instead of syntax. The reason is technical: HTML output requires entity escaping while terminal help and Markdown have other rules.

Review rendered output and original source separately, particularly values such as <FILE>. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Copy examples from the published page into a safe CLI test. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

35. Typed validations

A reliable investigation begins by reproducing this mismatch: The parser rejects an out-of-range value, but the localized message calls it an unknown option. It becomes understandable when we recognize that Conversion, validation and token recognition are distinct failure stages.

Explain the actual bound or expected type without claiming a different stage failed. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Exercise missing, malformed and out-of-range inputs separately. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

36. Security of logs

This case is easy to miss in an English-only review. A test publishes raw argv containing a token or personal path in a translation screenshot. Underneath the presentation, Command-line diagnostics may contain user-supplied information even when parsing fails.

Sanitize fixtures and avoid recording production secrets in public help or bug examples. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Inspect test logs for tokens, private paths and account identifiers before publication. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

37. Locale fallback

The observable problem is specific: A request for a nonexistent language yields English text and the page claims success. This is not just a wording issue. Resource-catalog selection is application behavior outside bpaf’s core parsing model.

Show a clear fallback indication and keep a supported-locale registry with the release. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Request an unsupported locale and verify the promised fallback occurs. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

38. Backward compatibility

Consider what the reader sees when a localized manual is used. A localization release changes alias definitions and breaks scripts created from the previous guide. The reason is technical: Executable tokens and parser output are an automation interface even when help is human-readable.

Freeze syntax for translation-only revisions; document any intended migration separately. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Replay saved commands across the old and new release artifacts. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

39. Cross-target builds

A reliable investigation begins by reproducing this mismatch: A test passes on the developer’s Linux machine but Windows terminal help and path handling differ. It becomes understandable when we recognize that Operating system, console, shell and Rust target all affect the user-visible command experience.

Include all supported targets in the testing matrix and disclose untested combinations. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Run the same harmless fixtures on actual target binaries. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

40. Reader comprehension

This case is easy to miss in an English-only review. The localized CLI passes snapshot tests but a new user still cannot tell what action a subcommand performs. Underneath the presentation, String equality tests cannot prove that a translated explanation supports a real task.

Observe a person completing a task from localized help without developer coaching. This protects both sides of the translation contract: the person needs an accurate instruction, and any existing script needs predictable accepted syntax and data types. When a sentence changes, verify that it has not introduced a claim about a default, side effect, platform or locale that the binary cannot support.

Ask them to predict effects, run the command and explain the returned result. Capture the actual argv supplied, parsed Rust value, help or diagnostic message, stdout and stderr, plus the process result when applicable. Repeat with another supported locale using the same fixture. A review is complete only when the reader-facing instruction and the observable program behavior agree.

An international release plan for maintainers

Begin with a parser inventory. Create a small table of every stable token, typed destination, default, valid choice, group, subcommand and environment source. Mark explanatory text separately from machine-facing values. Then translate only the approved human strings, maintaining a glossary for terms such as argument, flag, parameter, fallback and diagnostic.

Build a positive and negative test matrix that includes not only valid paths but also absent arguments, repeated arguments, invalid typed values, unsupported names and a help request. Record how each reaches bpaf and what the application does next. A parser error must not be reported as an application permission failure, and an application failure must not be disguised as a parser error.

Do not infer terminal quality from a browser preview. Capture the real release build at normal and narrow widths using a selection of Latin accents, CJK text and right-to-left descriptions. Check both visible wrapping and copyable command tokens. Accessibility review should also cover monochrome output and meaningful textual severity rather than color alone.

Treat completion and published reference pages as release artifacts. Generate them from the same parser version as the compiled program, and test candidates against accepted tokens. A translated completion label should not silently become a different option name. If a requested feature is unavailable in the pinned version, exclude it from the promise.

The last stage is a reader test. Give a multilingual user a harmless task such as displaying summary metadata from a bundled sample. Do not explain the flags verbally. If they can locate help, invoke the command, interpret a deliberate failure and recover, the documentation is doing its job. If they cannot, revise the specific step and rerun the observation.

Keep an explicit coverage statement: languages with complete application help, languages whose errors remain in English, shells with tested completion and operating systems with verified Unicode behavior. The statement is more useful than a vague ‘fully translated’ badge, and it prevents a writer from promising functions the library or product does not provide.

Frequently asked questions

Does bpaf include automatic translations for every help and error string?

No universal application localization should be assumed. Derive comments and explicit help descriptions are inputs to generated text, but locale selection and translation coverage are design and verification responsibilities.

What is the difference between derive and combinator usage?

Derive starts from annotated Rust types, while combinators explicitly compose parser values. Both aim at typed parse results; the translation workflow must inspect the syntax generated by the chosen design.

May we translate a short flag?

Not in a translation-only change without deliberately changing the executable interface. Translate the explanation first, preserve existing command lines and review compatibility if alternate localized aliases are required.

Why test ParseFailure independently?

Help and error outcomes can be represented differently. Their streams, status and reader meaning should not be guessed from one screenshot or collapsed into a generic exception message.

Is completion always available?

Completion depends on supported APIs and feature flags for the pinned version. Name the tested shells and verify that suggested values remain executable, rather than assuming universal support.

Can generated manpages replace CLI tests?

No. A manpage can be readable while the installed executable accepts other syntax. Compare artifacts derived from the same parser model and run the examples.

How should a Unicode path be tested?

Use a harmless fixture on each supported platform, record the actual OS argument representation and check where conversion or normalization occurs. Do not treat a visual match as proof of equal bytes.

What should remain stable for automation?

Accepted flags, subcommands, value grammar, machine-readable schemas and documented exit behavior should stay stable unless a separately reviewed interface change is planned.

Shipped-binary checklist

  1. Pin the Rust toolchain, bpaf version and enabled features.
  2. Build every supported target in a clean environment.
  3. Compare help and typed parse results before and after translation.
  4. Exercise invalid options, missing arguments, errors and help requests.
  5. Generate and inspect supported completion and documentation artifacts.
  6. Capture stdout, stderr and statuses for every failure class.
  7. Check CJK width, Arabic mixed direction, accents and narrow terminals.
  8. Validate clean-install behavior and catalog fallback in the packaged build.
  9. Ask users to execute harmless examples without developer assistance.

Official references and connected reading

Read the bpaf crate documentation for derive and combinator APIs, ParseFailure, OptionParser testing, completion and documentation generation. The broader Master Art of Translation explains meaning preservation, while the Translate Like a Pro series index connects adjacent frameworks. This guide is specifically about bpaf, not the separate Rust clap, getopts or clap-noun-verb tutorials.

A trustworthy localized Rust command line should behave exactly as its translated help predicts. Test the parser and the reader together: one controls what the program accepts, and the other determines whether that contract is understandable to the people using it.