What rtb-app does not do¶
A single page for every question whose honest answer is "no, that is not supported". Grouped by what you might have been trying to do.
It does not run a CLI¶
- No argument parsing. There is no
clapin this crate and no dependency on one.Command::runreceives anAppthat someone else built from arguments someone else parsed. That someone isrtb-cli. - No
--helpand no banner.CommandSpec::aboutandlong_aboutare strings this crate stores; rendering them isrtb-cli's job. - No dispatch.
BUILTIN_COMMANDSis a slice. Nothing inrtb-appreads it, filters it by the runtime feature set, deduplicates it or calls anything in it. - No process exit codes.
Command::runreturnsmiette::Result<()>; turning that into an exit status happens above.
It does not do I/O¶
- It does not read config files.
Appstores whateverConfig<C>it was handed. Layering, file discovery and merging arertb-config's. - It does not read or write assets.
App.assetsis anArc<Assets>fromrtb-assets, stored and handed back. - It does not resolve credentials. It enumerates what a
CredentialProviderreports. Reading a keychain, an environment variable or a file isrtb-credentials'. - It does not download, verify or install an update. Every
update_*field onToolMetadatais a declarationrtb-updateacts on. - It spawns no tasks. Nothing in this crate calls
tokio::spawn. The only async in it is theCommand::runsignature.
Things you cannot configure¶
App's shutdown token cannot be supplied.App::newalways creates a fresh rootCancellationToken. There is no parameter and no builder method, so anAppcannot be made a child of an outer cancellation scope at construction. Derive children fromapp.shutdownafter the fact.- The regex limits are fixed.
MAX_PATTERN_LEN(1 KiB),SIZE_LIMIT(1 MiB) andDFA_SIZE_LIMIT(8 MiB) arepub constwith no override. A tool needing different bounds builds its ownRegexBuilderand owns the risk. - There are no Cargo features. Neither crate declares any, so nothing here is
conditionally compiled and
default-features = falsechanges nothing. - Commands cannot be created at runtime. Every
CommandSpecfield is'static. A subcommand whose name comes from a config file is not expressible. - Pre-run hooks cannot capture state.
PreRunHookis afnpointer, not a closure. Everything a hook needs must come off theAppit is handed.
Combinations that do not work¶
- A typed config through
App::newgives you no schema.config_schema()andconfig_value()returnNoneunless aTypedConfigOpsbundle was attached viawith_typed_config.App::newcannot build one — its bound onCis onlyDeserializeOwned, while the bundle needsSerializeandJsonSchematoo. Sotyped_config::<C>()returningSomewhileconfig_schema()returnsNoneis a reachable and legitimate state. update_policyalone does nothing. It is inert unlessFeature::Updateis enabled andrelease_sourceis set. Setting it toEnabledon a tool with no release source changes nothing.- Signing keys cannot come from a config file.
update_public_keys,update_checksums_asset,update_asset_patternandtelemetry_noticeall carry#[serde(skip)]. And becauseToolMetadataisdeny_unknown_fields, putting one in a YAML document does not silently do nothing — it fails the whole parse. release_credentialdoes not round-trip. It deserialises and is never serialised back; it wraps a secret, and secrets do not leave throughSerialize.ReleaseSource::Giteahas no host default. Every other hosted variant defaults its host. Gitea cannot, because there is no public instance to default to. UseCodebergfor codeberg.org.
Silent failure modes¶
The things that go wrong without an error message. Each is covered in more detail on its own page; this is the checklist.
FeaturesBuilder::default()is empty,FeaturesBuilder::new()is the nine defaults. Reaching forDefault::default()out of habit ships a CLI with every built-in command hidden, and nothing warns.- A missing
#[distributed_slice]attribute compiles fine. The command simply never appears. Assert its name is inBUILTIN_COMMANDSin a test. VersionInfo::from_pkg_versionnever fails. An unparseable string becomes0.0.0with no error and no log line. The only signal is thatis_development()then returnstrue.VersionInfo::from_env()reports the wrong version. Deprecated since 0.9.0. It returns rtb-app's version rather than the calling tool's, which breaks self-update's post-download verification.TypedConfigOps::renderreturnsNoneon a type mismatch, with no error describing it — so a mismatched ops/config pair produces a permanently emptyconfig show.- Schema serialisation failure becomes
null.TypedConfigOps::newusesunwrap_or(Value::Null), so aJsonSchemaimplementation that fails to serialise yields anullschema rather than a message. - An empty credentials listing is indistinguishable from no provider. Both return
an empty
Vec. - A
Compileregex error covers two different problems. Invalid syntax and exceeding the memory bounds arrive as the same variant, under a message that reads as a size problem.
Ordering guarantees that do not exist¶
- Link-time registration order is not deterministic — for commands or for pre-run
hooks. Nothing that depends on which entry comes first is safe. Overriding a
built-in by re-registering its name relies on
rtb-cli's deduplication resolving the collision, not on any ordering this crate promises. Features::iter()has no defined order. It is backed by aHashSet. Sort before printing or comparing.Featuresdoes not implementPartialEq. Two sets cannot be compared with==.Appdoes not implementDebug. Printing one, or derivingDebugon a struct holding one, will not compile.