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 | 8830 — Rust bpaf Localization, Derive and Combinator Parsers, Help, Validation, Completion and Unicode QA

Rust bpaf localization means preparing understandable command-line help, argument labels, error explanations and completion descriptions without changing what a bpaf parser accepts. This practical guide covers searches for Rust bpaf help translation, Bpaf derive attributes, combinatoric parser documentation, OptionParser, ParseFailure, shell completion, Unicode and multilingual CLI testing. It distinguishes stable command syntax from text for human readers. The distinction matters because bpaf turns a composable parser definition into a working command; altering human-facing descriptions should not accidentally alter parser construction, typed results or validation.

Consider a fictional read-only note summary tool that takes a MESSAGE positional value and has a –verbose switch. A French-speaking reader needs to understand that the positional value is required and that –verbose requests additional explanation. Translating the words in the description is useful; replacing –verbose with a French phrase in documentation while the binary still expects –verbose is not. Similarly, changing a label in derive metadata is not the same as adding a command alias. A trustworthy guide has to demonstrate accepted inputs as well as good wording.

bpaf offers both derive and combinatoric approaches, parser transformations, generated usage, error outcomes, optional shell completion and documentation rendering features. This article explains how those parts interact, when a change belongs in source code versus translated help, how to investigate failures that appear only in another language, and how to test real commands rather than static screenshots. It moves from a safe example through parser design decisions, 25 distinctive troubleshooting cases, frequently asked questions and a four-week learning-to-release process.

At a glance: what must remain true

  • Keep the accepted parser syntax distinct from human translation.
  • Explain derive and combinatoric help where they are written.
  • Distinguish missing values, invalid values and intentional defaults.
  • Test completion, generated documents, Unicode and actual terminal behavior.

1. Start with bpaf’s two ways of expressing a parser

bpaf is a Rust command-line parsing library with combinatoric and derive-style APIs. The combinatoric form constructs parsers through functions such as positional, short, long and construct!, then turns the result into an OptionParser with to_options. The derive form describes fields and help through a structure and Bpaf attributes. These two styles can share the same underlying concepts but differ in where a translator or documentation editor encounters visible strings. First locate the definitive source for the accepted argument and its meaning, rather than assuming an option appears where its label is printed.

A novice can understand the difference by starting with one required positional message. In combinatoric code, positional(“MESSAGE”).help(“Message to show”) declares the argument and its explanation. In derive code, a field annotation can specify the positional label while its doc comment supplies help text. The string MESSAGE is a displayed placeholder rather than the user’s actual argument; the command still receives the typed value. Preserve example values that the parser can accept, and test whether the visible placeholder can be changed without changing behavior in your specific parser definition.

2. Define what is stable and what is localizable

A useful language inventory separates long switch names, short letters, subcommand names, value tokens, placeholders, help sentences, error messages, completion labels and structured output. Some are executable identifiers, some are explanatory text and some occupy both roles in a real application. For each, name the owner and confirm its intended stability. An editor should never create a new CLI spelling by translating a diagram, and a developer should not assume that an attractive translated usage line is consistent with the parser just because it compiles.

A CLI interface often becomes an informal API. Shell scripts can contain –format, completion definitions can look for a particular command name and tutorials can be copied for years. The simplest safe policy is to translate prose first and preserve stable tokens. If a product genuinely wants localized spellings, that becomes a software feature requiring aliases, compatibility decisions and thorough testing. State these layers explicitly near the beginning of the guide so users understand why some English-looking text remains unchanged in a French, Arabic or Japanese interface.

3. Use a harmless example that exposes the parser

The official bpaf quick start includes a struct with a single String message parsed positionally, and a combinatoric example showing how the pieces fit. That is a good instructional starting point because it has no file operations, network calls or silent side effects. The code below follows that minimal pattern and prints the parsed structure. It does not show a production translation catalog, argument validation beyond the parser, or an internationalized error hook. A responsible guide states what the example establishes and what remains to be implemented.

When writing translated help for this kind of program, keep the code path simple: one expected positional input, a generated –help screen and one invalid missing-value case. A reader can predict that an absent required message should not yield a successful Options value, while a supplied string can. Then compare two languages’ descriptions of that same contract. Do not introduce a complex subcommand or file path until the basic argument behavior and actual output have been established.

4. Help comes from the parser definition, not a separate fantasy

In bpaf, help text for derive mode may come from doc comments on fields and structures, while the combinatoric form uses methods such as help. The library also offers group_help, with_group_help, custom_usage and usage-related facilities for arranging how readers encounter choices. Each is useful for clarity, but changing a display string does not necessarily alter the accepted flags. Read the exact documentation for the installed bpaf version and confirm whether the product uses one parser style, the other or a mixture.

Help should answer four questions quickly: what is the task, what must the user provide, what optional controls exist, and what happens after a mistake. Avoid densely packed noun labels when a short verb phrase would explain the action. For a positional MESSAGE, a translation can clarify ‘Text to display’ and still retain an accurate command example. Where an English command token remains, explicitly show that it is to be typed literally. That is more useful than pretending every visible token can be translated independently.

5. Know the difference between absence and invalidity

The bpaf documentation distinguishes failures caused by an absent value from cases where a supplied value cannot be parsed or accepted. That matters because a missing –count is different from an unusable value such as –count many when the field expects a number. Parser transformations including optional, fallback, fallback_with, parse, map and guard shape the resulting value and its validation. A translated error should identify the actual decision that failed. Merely replacing all failures with ‘Please try again’ loses the information that makes recovery possible.

A fallback is not the same as accepting any input. It may supply a value when an item is absent, while invalid presence can require a separate decision. When a default is displayed, the value shown in help must match the parser’s real fallback. In a multilingual guide, write clear examples for ‘not supplied’, ‘supplied and valid’ and ‘supplied but invalid.’ This three-way comparison teaches the parser’s structure better than a long list of error words in isolation.

6. Named options and hidden aliases need careful governance

The long and short constructors describe accepted named arguments; bpaf documentation also discusses multiple names and hidden aliases. An alias supported in code is not automatically visible in help, and a visible help label is not automatically an alias. This distinction is central to localization. A team may wish to maintain –color for compatibility while offering a localized label in descriptive prose. That is safer than inventing an untested switch. If additional accepted aliases are added, reviewers should evaluate collisions, documentation clarity and backward compatibility.

Boolean switches, required flags, value-taking options and positional inputs are different objects. A –quiet switch might turn on a state; a –format json option requires a specific value; a required flag is not interchangeable with an optional switch. Show each with a valid example and make clear which layer supplies business constraints. Readers do not benefit from a translated label that hides the difference between a switch and a value. Test combined arguments in the exact parser the product ships.

7. Typed results improve translation when they are explained

One of bpaf’s strengths is that combinators can build structured Rust values rather than leaving every input as unvalidated strings. For mutually exclusive choices, an enum can encode exclusivity; for repeated values, a vector or collection can be appropriate. This affects how a translation should explain options. The guide should not promise that two exclusive flags can be used together when the parser maps them to a single enum variant. Likewise, repeated options are not necessarily cumulative unless the parser constructs a repeated collection.

A simple explanatory pattern is to name the user’s choice, show its valid syntax and state the resulting Rust value in ordinary language. Then add one deliberately invalid combination. For example, a report-mode enum might accept one of two flags, but not both; the actual names and error behavior must come from the source. This is more precise than a glossary of synonyms because it connects a visible instruction to the program’s data model. Avoid asserting automatic behavior for variants that the application has not defined.

8. Shell completion is another user interface, not proof of grammar

bpaf has optional autocomplete support, including completion methods and shell-specific features documented behind its Cargo feature configuration. Generated completion may suggest flags, commands or values, but its presence does not make every suggestion a translated sentence. Completion descriptions should tell users what candidates do without corrupting inserted tokens. A localized tooltip can be natural language; the replacement text delivered to the shell may need exact unchanged spelling. Treat the two fields as separate products of a completion system.

Completion behavior is also shell-dependent. A Bash test does not establish Zsh, Fish or Elvish behavior, even when the crate supports those shells. Test the package feature flags, the installed shell integration and the actual proposed insertion for a small disposable command. Do not advise readers to paste an untrusted completion script with elevated privileges. For a world-facing article, explain how to inspect suggestions and preserve machine-meaningful names without claiming that completion is enabled by default in every build.

9. Documentation rendering requires independent proofreading

bpaf documents optional docgen capabilities for rendering parser documentation in formats such as Markdown, HTML and manpage. Generating a file from parser metadata can reduce drift, but it does not guarantee that a long translated heading wraps well, that text is accessible or that a pasted command is correct. A publishing pipeline should compare generated pages with live –help output. Content can diverge when different builds enable different features or when the web format silently changes punctuation.

A helpful web guide supplements generated reference material with task explanations: which option to choose for a normal job, how to read the result and how to recover from likely mistakes. Keep machine syntax copyable in code blocks and avoid typographic substitutions of two hyphens. If the project uses translated strings at build time, ensure that both terminal and generated documentation refer to the same target locale and parser configuration. A document produced from an old crate version should not silently override the shipped binary’s behavior.

10. Unicode means more than a correct UTF-8 string literal

Rust string literals can contain international text, but the terminal still has its own renderer and operating-system argument handling. A translated help line can contain accented characters, Arabic script or Japanese punctuation and yet become difficult to scan in a narrow console. File paths are another layer: a PathBuf may represent data that cannot safely be converted to UTF-8 with a simple String operation. Do not replace a platform path with lossy text merely to make an error message printable.

Probe three distinct cases: translated descriptions in –help, international values that are genuine arguments, and paths or environment variables supplied through the operating system. Some failures arise from display width, some from shell quoting and some from incorrect conversions or normalization. Keep the error advice specific to the observed layer. A stable user journey is one in which the person can identify the right input and see a faithful outcome, not one in which every interface is forced into the same encoding assumptions.

11. Error output and exit codes are part of translation accuracy

ParseFailure can represent an unsuccessful parse or a help-oriented path; bpaf documentation describes ways to inspect outcomes and route them to streams or exit codes. A guide should not claim that every printed help message is an error, nor that all parser failures have an identical exit status. For tests, record the actual argument vector, expected human explanation, stdout, stderr and code. That evidence helps distinguish an error in application logic from a wording problem in the translated material.

Recovery instructions should be concise and specific. ‘The value after –count must be a whole number’ is more helpful than ‘Operation failed’, provided that is indeed the parser’s contract. A translation must preserve the rejection, not soften it into a suggestion that an invalid value will be accepted. At the same time, do not reveal full private paths, credentials or arbitrary untrusted input in diagnostics. The best message teaches the next safe action and exposes only details the reader needs.

12. Use a release contract rather than relying on screenshots

An international CLI guide should be tied to an actual crate version, feature set, binary and test corpus. Capture –help, a normal run, one missing required argument, a failed typed value and a completion example if enabled. Include the exact shell and locale context. This is a small reproducible contract, not an attempt to replace automated testing with editorial review. When the parser changes, reviewers know which examples need rerunning; when a language is added, they know which semantics must not drift.

Maintaining bpaf localization is easiest when syntax and prose have different owners. Developers keep parser construction and typed results correct; translators maintain action-led text; QA validates the full result in each environment. A competent reader can then choose a supported command without guessing whether translation altered the executable. The guiding standard is practical: the sentence should be understandable, the example should run and the observed result should match what the text promised.

A minimal Rust example you can inspect

This is a demonstration of bpaf’s combinatoric route from a positional argument to an OptionParser. It prints a Rust structure and intentionally has no file, network, translation catalog or configuration side effects. Compile against the documented crate version and run the generated –help screen. Use it to learn the boundary between a label and an accepted argument before adding any more elaborate localization architecture.

use bpaf::*;

#[derive(Debug, Clone)]
struct Options {
    message: String,
}

fn options() -> OptionParser<Options> {
    let message = positional("MESSAGE").help("Text to display");
    construct!(Options { message }).to_options()
}

fn main() {
    println!("{:?}", options().run());
}
// Report only: this example does not open files or send data.

For a safe run, supply a quoted message such as ‘Hello world’. A missing message is the useful negative test. The string MESSAGE is a visible placeholder; the user’s literal message is the parsed value. To translate the helper sentence, change only the prose passed to help in the appropriate parser definition. A larger application may draw that sentence from a locale resource, but this example makes no claim to implement such a resource mechanism.

Twenty-five framework-specific investigations

Troubleshooting begins by identifying which visible layer has failed. The following scenarios distinguish parser grammar, generated documentation, shell behavior, data types and ordinary language. All examples can be rehearsed with fictional strings and disposable files; none require modifying a live user environment.

1. The translated manual invents a new long switch

Symptom. A Spanish-language instruction prints –mensaje for a program whose parser only accepts MESSAGE as a positional value and has no –mensaje flag.

Explanation. An explanatory label and a registered option are different concepts; using natural language in a command example does not register it with bpaf.

Remedy. Keep the actual positional syntax and translate the description around MESSAGE. Introduce a new flag only as an intentional parser feature.

Test. Run the command exactly as published, including any new alias, and compare its parsed Options value to the original specification.

2. The derive annotation is confused with the help sentence

Symptom. A reviewer changes #[bpaf(positional(“MESSAGE”))] thinking it is a user-facing sentence while leaving an inaccurate doc comment untouched.

Explanation. Derive attributes shape how a field is parsed and displayed; the comment can communicate its purpose separately.

Remedy. Locate both the annotation and the doc comment; make precise changes based on whether the requested difference is grammar or explanation.

Test. Generate –help from the same build and run one positional input to confirm the parser’s accepted behavior did not drift.

3. A missing positional is described as optional

Symptom. The localized guide says a note can be omitted, although positional(“MESSAGE”) in the simple example expects a value.

Explanation. A translator may treat a friendly placeholder as optional text rather than a required input to the constructed parser.

Remedy. Tell the reader that this demonstration requires one message and show a harmless quoted sample to try.

Test. Invoke the program without an argument and record its actual outcome before writing the recovery advice.

4. An invalid value is treated like absence

Symptom. A developer attaches fallback to a parser and documents that it will repair any malformed value as well as an omitted value.

Explanation. bpaf distinguishes an absent item from an item that is present but fails parsing or validation; a fallback may not cover both cases.

Remedy. Explain which missing case receives a default and which invalid case requires a correction, using the exact combinator chain.

Test. Test no input, valid input and invalid input separately, observing the resulting value or ParseFailure.

5. A Boolean switch is shown with a string value

Symptom. A help page suggests –verbose yes, but the source uses long(“verbose”).switch() which does not require a value.

Explanation. Switches and value-taking arguments have different syntax, even if an everyday language phrase mentions a state or choice.

Remedy. Present –verbose alone when that is what the parser accepts and place the translated explanation next to it.

Test. Compare the accepted command with –verbose yes, inspecting whether the extra token becomes unexpected input.

6. A hidden alias is advertised as an ordinary choice

Symptom. An older alternate spelling is retained in source as a hidden alias, while a translated guide treats it as the main public interface.

Explanation. An alias’s existence does not mean product documentation should emphasize it, and unsupported spellings should not be implied.

Remedy. Lead with the visible canonical name; mention compatibility aliases only if the product intentionally documents them.

Test. Run tests for old and new spellings, then examine –help to verify which one is actually visible.

7. Mutually exclusive flags are taught together

Symptom. The sample reference constructs an enum from alternatives, but an example includes both exclusive flags in one invocation.

Explanation. A parser that produces only one enum variant cannot necessarily combine two simultaneous choices.

Remedy. Explain the mutually exclusive decision in task language and demonstrate one valid command for each branch.

Test. Try both flags together and confirm the parser’s observed rejection rather than creating a fictional combined result.

8. A repeated value is described as singular

Symptom. The user can supply several –tag occurrences, but the translation says only the last tag will be used without checking the collection logic.

Explanation. Repeated results depend on whether the parser uses many, some, collect or another composition, not on the word ‘tag’.

Remedy. Describe the actual aggregation semantics and show two distinct harmless values if repetition is supported.

Test. Inspect the resulting Vec or other collection and verify the number and order of values as the guide claims.

9. A default value shown in help is out of date

Symptom. The parser’s fallback changed from text to json, but old localized screenshots still say that text is selected when no mode is given.

Explanation. A fallback in source and a displayed fallback explanation can evolve independently, creating misleading assurances.

Remedy. Update human wording from the current parser definition and use a documented help-format mechanism where applicable.

Test. Run the no-argument case and compare the result with the published default in each locale.

10. A guard failure is presented as a successful warning

Symptom. A localized message says ‘consider choosing a positive number’ even though guard rejects a negative count.

Explanation. A parse-time validation rule is a hard constraint; friendly tone must not imply that the invalid command can proceed.

Remedy. Say plainly that the value is not accepted, show the supported range if verified, and provide a safe example.

Test. Test both sides of the boundary and inspect whether the parser produces a valid Options object.

11. A shell suggestion inserts a translated token

Symptom. A completion popup describes a language choice in French but inserts an invented translated option name.

Explanation. Completion insertion is executable text; its description can be translated without changing that text.

Remedy. Keep candidate values and option identifiers stable unless localized names are implemented in the command parser.

Test. Accept a completion and execute the result; the command must parse in the same binary that generated the suggestion.

12. The autocomplete feature is assumed always enabled

Symptom. The documentation promises shell completion but the production Cargo features do not include the required support.

Explanation. bpaf’s autocomplete functionality is feature-gated; examples from full-featured documentation may not reflect a minimal build.

Remedy. State the feature requirement and show a testable configuration only for installations that actually enable it.

Test. Inspect Cargo.toml and run completion against the released binary, not a local development build with extra features.

13. Generated Markdown diverges from terminal help

Symptom. A website displays generated documentation from a newer crate configuration while the installed tool offers fewer options.

Explanation. Doc generation and binary compilation can use different feature sets, versions or parser definitions if not coordinated.

Remedy. Pin generation to the release and supplement it with tested usage notes for the same binary.

Test. Compare the option inventory in rendered Markdown with –help output from the release artifact.

14. Right-to-left help makes ASCII switches hard to read

Symptom. An Arabic help paragraph mixes Latin option strings and punctuation, so the visible order is ambiguous on a terminal.

Explanation. Bidirectional rendering can rearrange code-like tokens even when underlying strings are unchanged.

Remedy. Keep option tokens visually isolated and test suitable direction settings on the actual supported renderer.

Test. Copy a displayed switch into a shell and check its bytes and parse result, not just visual appearance.

15. An untrusted error prints a sensitive path

Symptom. A parser failure echoes the entire local home-directory path and private filename in help text even though the user needs only a value hint.

Explanation. Raw input may contain personal or secret information; translated diagnostics should not expose more than necessary.

Remedy. Explain the expected value category and use safe excerpts or redaction where the application controls the message.

Test. Trigger a harmless invalid path in a temporary directory and review stdout, stderr and logs for leaks.

16. A typed numeric argument is documented as arbitrary prose

Symptom. The tutorial allows –count many even though the parser expects a Rust integer through FromStr or a custom parser.

Explanation. The help’s everyday word ‘count’ is not the actual grammar of the typed destination.

Remedy. Specify a parseable numeric example and separately document limits enforced by guard or later application code.

Test. Run a valid integer and a word value to identify whether parsing or business validation rejects the command.

17. A PathBuf is converted through lossy text

Symptom. A file path with a valid platform representation is forced through a UTF-8 conversion for a translated error, altering the name.

Explanation. Rust’s OsString and PathBuf can represent operating-system values that should not be assumed to be ordinary String text.

Remedy. Preserve the path for operations and choose a safe display representation only for human explanation.

Test. Use disposable non-ASCII and platform-specific names, confirming identity is preserved after the error is reported.

18. A colored help theme becomes unreadable

Symptom. The chosen bpaf color feature looks legible on one terminal but loses contrast in a different theme or redirected output.

Explanation. Terminal color support, background and pipe behavior vary; a pretty local screenshot is incomplete evidence.

Remedy. Treat color as an enhancement and verify plain output, contrast and copied command tokens.

Test. Test normal, redirected and narrow output with the release’s actual Cargo feature selection.

19. A custom usage line omits a required operand

Symptom. An editor replaces generated usage with a shorter translated sentence but forgets the required MESSAGE position.

Explanation. Custom usage controls the visible explanation but must still tell the truth about parsed requirements.

Remedy. Audit every usage placeholder against the parser tree and keep essential operands visible.

Test. Ask a new reader to run a complete sample from only the localized help screen.

20. A help group hides a consequential switch

Symptom. The language team groups options under a broad heading, making a required choice hard to discover.

Explanation. Group headings organize display; they do not replace clear information about requirements, defaults or effects.

Remedy. Give groups task-based names and make constraints legible next to affected options.

Test. Observe whether a target-language reader can locate and choose the needed switch without extra explanation.

21. A parser error is mistaken for an application network failure

Symptom. A missing argument produces a ParseFailure, but the translated guide tells the user to check connectivity.

Explanation. Input parsing can fail before any application or network work begins, so that advice wastes time.

Remedy. Write recovery language that identifies the missing or malformed token instead of inventing a downstream dependency.

Test. Run the invalid command in an offline test and inspect the failure stage and exit status.

22. Unexpected extra words are silently omitted from guidance

Symptom. A user supplies a valid message and an extra word; documentation pretends the parser will always concatenate them.

Explanation. A positional parser may accept only the intended number of tokens unless configured to collect more.

Remedy. Explain quoting and exact positional cardinality, and show how the shell splits words.

Test. Compare one quoted argument with two unquoted tokens and examine the parsed result.

23. A command example uses an en dash in place of two hyphens

Symptom. The CMS converts –help into a typographic dash, creating a visually similar but unrecognized shell token.

Explanation. Unicode punctuation is not interchangeable with the ASCII characters used in command syntax.

Remedy. Use code blocks and preserve exact source bytes in every copyable command.

Test. Copy from the published page into the target terminal and inspect the actual result.

24. A translated error implies a bad value was accepted

Symptom. The message says ‘value adjusted’ after a guard rejected input and produced no valid options.

Explanation. Localization has changed the force of an error, confusing readers about whether work proceeded.

Remedy. Preserve rejection language and state the corrective action; avoid implying a fallback that the parser did not use.

Test. Compare the failed run’s exit code and absence of normal output to the translated explanation.

25. A release note claims all shells behave identically

Symptom. Completion and Unicode behavior are checked in Bash only, but documentation promises identical rendering in every supported shell.

Explanation. Shell quoting, insertion and display vary; bpaf’s support for several shells is not a guarantee of identical UX.

Remedy. List tested shells, feature flags and limitations, and avoid universal compatibility claims unsupported by evidence.

Test. Capture the same command and completion journey in each supported shell before publishing a blanket claim.

Frequently asked questions

Should I choose bpaf derive or combinatoric APIs for localization?

Either can support understandable help. Derive uses field attributes and documentation comments; combinatoric code attaches descriptions to parser-building expressions. Choose based on the codebase’s maintainability, then keep accepted syntax separate from human wording.

Can I translate long option names?

Only when the binary supports the new names. Translating the explanation is usually safer, especially when commands are copied into scripts. If new aliases are added, document which spelling is canonical and test compatibility.

Does bpaf turn every invalid value into a fallback?

No. The library distinguishes missing from present-but-invalid input, and combinators handle cases differently. Check the exact parser chain and write examples for absence, valid presence and invalid presence.

How do I show a default in translated help?

First verify that a fallback exists and which value it produces. Then use the documented formatting methods that apply to your crate version, or accurate surrounding prose. A translated default should match a no-option run.

What does ParseFailure tell testers?

It represents an unsuccessful or help-oriented parser outcome that can be inspected in tests and routed to an output stream or exit status. Record the exact source command, outcome and displayed explanation rather than assuming every failure is identical.

Does bpaf support shell completion in every installation?

Completion support is available behind relevant Cargo features and shell integration. Confirm the released feature configuration, test actual inserted tokens and keep explanatory tooltip localization separate from executable completion candidates.

What is the safest first Unicode test?

Use a translated –help description and a harmless quoted international message. Then separately test filesystem paths or environment variables where the app uses them. Test terminal display and argument preservation as distinct concerns.

How should a team prevent future translation drift?

Pin the crate release and feature set, archive help and error snapshots, and compare generated documentation to the shipped binary. Re-run the same safe command corpus when parser declarations or supported languages change.

Four-week route from understanding to release

Week 1 — audit the parser tree

Identify whether each command uses derive, combinatoric syntax or a mixture. Inventory short and long flags, positional arguments, enum alternatives, subcommands and parser transformations. Record crate version and Cargo features. Run the release’s help path and a few intentionally invalid commands. Identify which labels are translatable help, which strings are parser grammar and which results are machine-level identifiers. Save a baseline command corpus for later comparison.

Week 2 — write useful multilingual help

Translate each description as a user action with a concrete outcome. Keep registered option names stable, show required values and real defaults, and distinguish Boolean switches from value-taking options. Check derive comments and combinatoric help methods against the same interface. Try translated headings at narrow widths and ensure examples copy correctly. Have a fluent reader explain how to recover from a missing argument without assistance.

Week 3 — test errors, completion and Unicode

Exercise missing positional input, malformed typed values, rejected guard rules, exclusive options, repeated inputs and valid defaults. Where autocomplete is enabled, test suggestions and inserted tokens in each supported shell. Generate documentation from the released parser and compare it with terminal help. Include non-ASCII messages and disposable Unicode paths, recording display, byte preservation, stdout, stderr and exit status. Separate platform limitations from genuine translation defects.

Week 4 — prove the guide works end to end

Give a target-language reader a test binary and the draft guide. Ask them to find a command, choose an option, run it, notice one deliberate mistake and recover. Observe whether any translated phrase suggests unsupported grammar or a default the parser does not have. Repair those passages, re-run the command corpus and review the packaged version and features. Store examples with test evidence so future Rust changes cannot silently invalidate the article.

What successful bpaf localization feels like

A user should be able to see an option, understand its real effect, provide a typed value and repair a predictable mistake without guessing. A developer should be able to compare the guide with the parser and prove that the same commands still work in every supported language. bpaf’s composable types, derived help and optional completion can support that experience, but only when display, grammar and validation remain consistent. Measure progress by the reader’s completed task, not by the number of translated words.

Primary technical references and next reading