- Introduction
- At-a-glance breaking changes
- 1. Update crate versions and feature flags
- 2. Simplify imports using the new re-exports
- 3. Adopt declarative configuration discovery
- 4. Handle stricter discovery outcomes
- 5. Switch to the stricter YAML provider
- 6. Review documentation and release notes
This guide describes how to upgrade applications from ortho-config v0.5.0 to
v0.6.0. The release focuses on removing redundant dependencies, improving
configuration discovery, and tightening YAML parsing semantics. Each section
explains the change, why it matters, and how to adapt code. For concrete usage,
review the hello_world example
(https://github.com/leynos/ortho-config/tree/main/examples/hello_world)
throughout.
| Area | Impact | Section |
|---|---|---|
| Dependency surface | Macro crate now inherits parser features and consumes the re-exported dependency graph. | 1, 2 |
| Discovery | Declarative attributes replace bespoke builders, altering discovery configuration points. | 3 |
| Error handling | ConfigDiscovery::load_first now errors when every candidate fails, affecting control flow. |
4 |
| YAML parsing | SaphyrYaml replaces the Figment YAML provider and enforces YAML 1.2 semantics. |
5 |
ortho_config = "0.5"
ortho_config_macros = { version = "0.5", features = ["yaml"] }ortho_config = { version = "0.6.0", features = ["yaml"] }
ortho_config_macros = "0.6.0"- Change every
ortho_configdependency (workspace metadata, application crates, and supporting tools) to"0.6.0". This keeps the runtime crate and the derive macro in lockstep, ensuring generated code matches the new library behaviour. - Retain any optional features (such as
json5,yaml, ortoml) on the mainortho_configdependency. The macro crate now inherits those flags, removing the need for duplicate feature declarations onortho_config_macros.1 - Rebuild the project to confirm the upgraded macro compiles cleanly before proceeding with behavioural changes.
The hello_world example continues to expose feature toggles via the parent
crate so that enabling json5, yaml, or toml automatically propagates to
both the runtime and macro crates.2
Version 0.6.0 re-exports figment, uncased, xdg, and the optional format
parsers directly from ortho_config, meaning downstream crates can remove
explicit dependencies on those packages.3 Update import paths to use
ortho_config::figment (and similar paths) instead of referring to the crates
independently. The hello_world example demonstrates this pattern when loading
configuration files and writing integration tests.4
use figment::providers::{Format, Toml};
use ortho_config::ConfigBuilder;use ortho_config::figment::providers::{Format, Toml};
use ortho_config::ConfigBuilder;Once the imports are adjusted, prune redundant dependencies from each
Cargo.toml. Rebuilding after the clean-up confirms the slimmer dependency set.
A new #[ortho_config(discovery(...))] attribute enables customised discovery
without bespoke builders for every CLI entry point.5 This
attribute mirrors the builder capabilities: specify the config file name,
dotfile name, project-level override, the generated --config flag, and the
corresponding environment variable prefix.
impl HelloWorldCli {
pub fn discovery() -> ConfigDiscovery {
ConfigDiscovery::builder()
.global_file_name("hello-world.toml")
.dotfile_name(".hello-world.toml")
.build()
}
}#[derive(ortho_config::Config)]
#[ortho_config(discovery(
global_file_name = "hello-world.toml",
dotfile_name = ".hello-world.toml",
env_prefix = "HELLO_WORLD"
))]
pub struct HelloWorldCli {
// fields
}Apply the attribute to root config structs to remove manual builder calls. The
hello_world CLI uses the attribute to declare its TOML locations while
retaining a shared helper for non-derive consumers that need direct access to
the discovery builder.6
When programmatic discovery is required elsewhere (for example, to present the
candidate paths), keep helper functions that reuse ConfigDiscovery::builder.
Those helpers now benefit from the clarified error behaviour described next.
ConfigDiscovery::load_first now returns an error when every candidate path
fails to load and at least one of them produced an error. It only returns
Ok(None) when no candidates were available. Callers should bubble up the new
error instead of silently falling back to defaults.
In the hello_world example the shared discovery helper maps the error into
HelloWorldError7, ensuring the CLI exits with actionable
diagnostics when misconfigured files exist.8
match discovery.load_first()? {
Some(config) => Ok(config),
None => Ok(default_config()),
}let config = discovery.load_first().map_err(HelloWorldError::Load)?;
match config {
Some(config) => Ok(config),
None => Ok(default_config()),
}Call sites that previously matched on Ok(None) to continue running with
defaults should be audited. After upgrading, consider whether those branches
now ought to abort with an error, so broken configuration files do not pass
unnoticed.
The legacy serde_yaml integration has been replaced with a new SaphyrYaml
provider backed by serde-saphyr. The parser enforces YAML 1.2 rules, so
tokens like yes remain strings unless quoted and duplicate mapping keys
produce structured errors.9
If an application reads YAML, enable the yaml feature on ortho_config and
switch to SaphyrYaml::file (or ::string for inline fixtures) wherever the
Figment YAML provider was previously used. The new provider supports the same
profile controls, so most call sites simply update the constructor name.
use ortho_config::figment::providers::YamlExtended;
Figment::from(YamlExtended::file("hello-world.yaml"))use ortho_config::file::SaphyrYaml;
Figment::from(SaphyrYaml::file("hello-world.yaml"))The hello_world example exposes the YAML provider through integration tests
that merge inline YAML fragments into the global configuration, exercising the
strict parsing mode.10
After the code changes, internal documentation or runbooks should be updated to reflect the new dependency graph, discovery behaviour, and YAML semantics. The v0.6.0 CHANGELOG entries provide a concise summary for release announcements.11
* ortho-config v0.5.0 provides YAML parsing via serde_yaml.* ortho-config v0.6.0 provides YAML parsing via SaphyrYaml (serde-saphyr).Once everything compiles and tests pass, the upgraded configuration experience is ready for release.
Footnotes
-
Optional parser features on
ortho_configautomatically enable matching flags on the macro crate, keeping generated code in sync with runtime capabilities.【F:ortho_config/Cargo.toml†L41-L45】 ↩ -
The
hello_worldcrate forwards its parser feature flags toortho_config, so enabling a format once covers both runtime and macro usage.【F:examples/hello_world/Cargo.toml†L23-L33】 ↩ -
ortho_configre-exports Figment, optional parser crates, and supporting utilities for consumers, eliminating redundant direct dependencies.【F:ortho_config/src/lib.rs†L11-L61】 ↩ -
The
hello_worldexample pulls Figment providers from theortho_confignamespace when layering configuration data. 【F:examples/hello_world/src/cli/config_loading.rs†L1-L60】 It reuses the same imports in tests to assert behaviour under YAML overrides. 【F:examples/hello_world/src/cli/tests/overrides.rs†L125-L155】 ↩ -
The derive macro accepts a
discovery(...)attribute on config structs, enabling declarative discovery policies.【F:examples/hello_world/src/cli/mod.rs†L174-L211】 ↩ -
The CLI struct uses the discovery attribute to define file names, CLI flags, and environment overrides without manual builder plumbing.【F:examples/hello_world/src/cli/mod.rs†L174-L211】 ↩
-
ConfigDiscovery::load_firstnow aggregates discovery errors, returningErrwhenever every candidate fails but at least one error occurred.【F:ortho_config/src/discovery/mod.rs†L305-L318】 ↩ -
The shared discovery helper wraps
ConfigDiscovery::load_firstand maps aggregated errors intoHelloWorldErrorfor callers.【F:examples/hello_world/src/cli/discovery.rs†L1-L36】 ↩ -
The
SaphyrYamlprovider reads files with strict YAML 1.2 semantics and backs the format-specific branch ofparse_config_by_format. 【F:ortho_config/src/file/mod.rs†L34-L86】 【F:ortho_config/src/file/mod.rs†L253-L296】 ↩ -
Behavioural tests in
hello_worldcreate YAML fixtures, load them throughortho_config::load_config_file, and assert strict parsing behaviour.【F:examples/hello_world/src/cli/tests/overrides.rs†L125-L155】 ↩ -
The Unreleased changelog summarises the v0.6.0 additions and behaviour changes discussed in this guide.【F:CHANGELOG.md†L6-L26】 ↩