rust-config-tree handleiding
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Dit is de Nederlandse handleiding voor rust-config-tree.
Begin met Introductie, Snelstart of de uitvoerbare Voorbeelden.
Introductie
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
rust-config-tree biedt herbruikbare configuratieboomlading en CLI-hulpmiddelen
voor Rust-toepassingen die gelaagde configuratiebestanden gebruiken.
De crate is ontworpen rond een kleine verdeling van verantwoordelijkheden:
confiquebezit schemadefinities, codestandaarden, validatie en generatie van configuratiesjablonen.figmentbezit runtime laden en runtime bronmetadata.rust-config-treebezit recursieve include-traversal, oplossen van include-paden,.envladen, ontdekking van sjabloondoelen en herbruikbare clap-opdrachten.
De crate is nuttig wanneer een toepassing een natuurlijke configuratie-indeling zoals deze wil:
include:
- config/server.yaml
- config/database.yaml
log:
level: info
Elk geinclude bestand kan dezelfde schemavorm gebruiken, en relatieve
include-paden worden opgelost vanuit het bestand dat ze declareerde. De
uiteindelijke configuratie is nog steeds een normale confique-schemawaarde.
Hoofdfuncties
- Recursieve include-traversal met cycledetectie.
- Relatieve include-paden opgelost vanuit het declarerende bestand.
.envladen voordat omgevingsproviders worden geevalueerd.- Door het schema gedeclareerde omgevingsvariabelen zonder delimiter-splitting.
- Figment-metadata voor runtime brontracking.
- Brontrackingevents op TRACE-niveau via
tracing. - Draft 7 JSON Schema-generatie voor editorcompletion en basale schemacontroles.
- Veldwaardevalidatie in toepassingscode met
#[config(validate = Self::validate)], uitgevoerd doorload_configofconfig-validate. - YAML-, TOML-, JSON- en JSON5-sjabloongeneratie.
- TOML
#:schema, YAML Language Server-schemamodelines en JSON/JSON5$schema-velden voor gegenereerde sjablonen. - Opt-in YAML-sjabloonsplitsing voor secties gemarkeerd met
x-tree-split. - Ingebouwde clap-subcommands voor configuratiesjablonen, JSON Schema en shellcompletions.
- Een lagere tree-API voor callers die geen
confiquegebruiken.
Publieke entrypoints
Gebruik deze API’s voor de meeste toepassingen:
load_config::<S>(path)laadt het uiteindelijke schema.load_config_with_figment::<S>(path)laadt het schema en retourneert de Figment-grafiek die voor brontracking wordt gebruikt.write_config_templates::<S>(config_path, output_path)schrijft het rootsjabloon en recursief ontdekte kindsjablonen.write_config_schemas::<S>(output_path)schrijft root- en sectie-Draft 7 JSON Schemas.handle_config_command::<Cli, S>(command, config_path)verwerkt ingebouwde clap-configuratieopdrachten.
Gebruik load_config_tree wanneer je de traversalprimitive zonder confique
nodig hebt.
Snelstart
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Voeg de crate en de schema/runtime-bibliotheken toe die je toepassing gebruikt:
[dependencies]
rust-config-tree = "0.1"
confique = { version = "0.4", features = ["yaml", "toml", "json5"] }
figment = { version = "0.10", features = ["yaml", "toml", "json", "env"] }
schemars = { version = "1", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
clap = { version = "4", features = ["derive"] }
Definieer een confique-schema en implementeer ConfigSchema voor het roottype:
#![allow(unused)]
fn main() {
use std::path::PathBuf;
use confique::Config;
use rust_config_tree::ConfigSchema;
#[derive(Debug, Config)]
struct AppConfig {
#[config(default = [])]
include: Vec<PathBuf>,
#[config(nested)]
server: ServerConfig,
}
#[derive(Debug, Config)]
struct ServerConfig {
#[config(default = "127.0.0.1")]
#[config(env = "APP_SERVER_BIND")]
bind: String,
#[config(default = 8080)]
#[config(env = "APP_SERVER_PORT")]
port: u16,
}
impl ConfigSchema for AppConfig {
fn include_paths(layer: &<Self as Config>::Layer) -> Vec<PathBuf> {
layer.include.clone().unwrap_or_default()
}
}
}
Laad de configuratie:
#![allow(unused)]
fn main() {
use rust_config_tree::load_config;
let config = load_config::<AppConfig>("config.yaml")?;
println!("{config:#?}");
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Gebruik een rootbestand met recursieve includes:
# config.yaml
include:
- config/server.yaml
# config/server.yaml
server:
bind: 0.0.0.0
port: 3000
De standaardprioriteit van load_config is:
environment variables
> config files, with later merged files overriding earlier files
> confique code defaults
Wanneer includes door de high-level API worden geladen, heeft het rootbestand de hoogste bestandsprioriteit. Geinclude bestanden leveren waarden met lagere prioriteit en kunnen worden gebruikt voor defaults of sectiespecifieke bestanden.
Commandoregelargumenten zijn toepassingsspecifiek, dus load_config leest ze
niet automatisch. Voeg CLI-overrides samen na build_config_figment wanneer de
toepassing configuratie-overridevlaggen heeft:
CLI-vlagnamen worden door de toepassing gekozen. Ze zijn niet automatisch
a.b.c-configuratiepaden. Geef de voorkeur aan normale clap-vlaggen zoals
--server-port en map ze daarna naar een geneste overridestructuur. De geneste
geserialiseerde vorm bepaalt welke configuratiesleutel wordt overschreven.
Alleen waarden die in de CliOverrides-provider van de toepassing zijn
opgenomen, overschrijven configuratie. Dit is nuttig voor parameters die vaak
voor een enkele run worden gewijzigd zonder het configuratiebestand aan te
passen. Stabiele waarden horen in configuratiebestanden.
#![allow(unused)]
fn main() {
use figment::providers::Serialized;
use serde::Serialize;
use rust_config_tree::{build_config_figment, load_config_from_figment};
#[derive(Debug, Serialize)]
struct CliOverrides {
#[serde(skip_serializing_if = "Option::is_none")]
server: Option<CliServerOverrides>,
}
#[derive(Debug, Serialize)]
struct CliServerOverrides {
#[serde(skip_serializing_if = "Option::is_none")]
port: Option<u16>,
}
let cli_overrides = CliOverrides {
server: Some(CliServerOverrides { port: Some(9000) }),
};
let figment = build_config_figment::<AppConfig>("config.yaml")?
.merge(Serialized::defaults(cli_overrides));
let config = load_config_from_figment::<AppConfig>(&figment)?;
let _ = config;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Met CLI-overrides die zo worden samengevoegd, is de volledige prioriteit:
command-line overrides
> environment variables
> config files
> confique code defaults
Configuratieschema
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Toepassingsschema’s zijn normale confique-configuratietypen. Het rootschema
moet ConfigSchema implementeren zodat rust-config-tree recursieve includes
uit de tussenliggende confique-laag kan ontdekken.
#![allow(unused)]
fn main() {
use std::path::PathBuf;
use confique::Config;
use schemars::JsonSchema;
use rust_config_tree::ConfigSchema;
#[derive(Debug, Config, JsonSchema)]
struct AppConfig {
#[config(default = [])]
include: Vec<PathBuf>,
#[config(nested)]
#[schemars(extend("x-tree-split" = true))]
database: DatabaseConfig,
}
#[derive(Debug, Config, JsonSchema)]
struct DatabaseConfig {
#[config(env = "APP_DATABASE_URL")]
url: String,
#[config(default = 16)]
#[config(env = "APP_DATABASE_POOL_SIZE")]
pool_size: u32,
}
impl ConfigSchema for AppConfig {
fn include_paths(layer: &<Self as Config>::Layer) -> Vec<PathBuf> {
layer.include.clone().unwrap_or_default()
}
}
}
Include-veld
Het include-veld mag elke naam hebben. rust-config-tree kent het alleen via
ConfigSchema::include_paths.
Het veld heeft normaal een lege default:
#![allow(unused)]
fn main() {
#[config(default = [])]
include: Vec<PathBuf>,
}
De loader ontvangt voor elk bestand een gedeeltelijk geladen laag. Daardoor kan hij kindconfiguratiebestanden ontdekken voordat het uiteindelijke schema wordt samengevoegd en gevalideerd.
Geneste secties
Gebruik #[config(nested)] voor gestructureerde secties. Geneste secties
worden altijd gebruikt voor runtime laden. Voeg
#[schemars(extend("x-tree-split" = true))] toe wanneer een genest veld ook
als eigen *.yaml-sjabloon en <section>.schema.json-schema moet
worden gegenereerd:
#![allow(unused)]
fn main() {
#[derive(Debug, Config, JsonSchema)]
struct AppConfig {
#[config(nested)]
#[schemars(extend("x-tree-split" = true))]
server: ServerConfig,
}
}
De natuurlijke YAML-vorm is:
server:
bind: 127.0.0.1
port: 8080
Omgevings-only velden
Markeer een leafveld met #[schemars(extend("x-env-only" = true))] wanneer de waarde alleen uit een omgevingsvariabele mag komen en niet in gegenereerde configuratiebestanden mag verschijnen. Gegenereerde YAML-sjablonen en JSON Schemas laten env-only velden weg, en lege bovenliggende objecten die daardoor overblijven worden verwijderd.
#![allow(unused)]
fn main() {
#[config(env = "APP_SECRET")]
#[schemars(extend("x-env-only" = true))]
secret: String,
}
Veldwaardevalidatie
Gegenereerde *.schema.json-bestanden zijn alleen voor IDE-completion en basale
editorcontroles. Ze bepalen niet of een concrete veldwaarde geldig is voor de
toepassing.
Veldwaardevalidatie moet in code worden geimplementeerd met
#[config(validate = Self::validate)]. De validator draait wanneer de
uiteindelijke configuratie wordt geladen met load_config of gecontroleerd met
config-validate.
Overrides voor sjabloonsecties
Wanneer een sjabloonbron geen includes heeft, kan de crate kind-
sjabloonbestanden afleiden uit geneste schemaselecties gemarkeerd met x-tree-split. Het standaardpad op het
hoogste niveau is <section>.yaml.
Overschrijf dat pad met template_path_for_section:
#![allow(unused)]
fn main() {
impl ConfigSchema for AppConfig {
fn include_paths(layer: &<Self as Config>::Layer) -> Vec<PathBuf> {
layer.include.clone().unwrap_or_default()
}
fn template_path_for_section(section_path: &[&str]) -> Option<PathBuf> {
match section_path {
["database"] => Some(PathBuf::from("examples/database.yaml")),
_ => None,
}
}
}
}
Runtime laden
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Runtime laden is bewust verdeeld tussen Figment en confique:
figment:
runtime file loading
runtime environment loading
runtime source metadata
confique:
schema metadata
defaults
validation
config templates
De hoofd-API is:
#![allow(unused)]
fn main() {
use rust_config_tree::load_config;
let config = load_config::<AppConfig>("config.yaml")?;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Gebruik load_config_with_figment wanneer de toepassing bronmetadata nodig heeft:
#![allow(unused)]
fn main() {
use rust_config_tree::load_config_with_figment;
let (config, figment) = load_config_with_figment::<AppConfig>("config.yaml")?;
let _ = (config, figment);
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Laadstappen
De high-level loader voert deze stappen uit:
- Los het rootconfiguratiepad lexicaal op.
- Laad het eerste
.env-bestand dat wordt gevonden door omhoog te lopen vanaf de rootconfiguratiedirectory. - Laad elk configuratiebestand als gedeeltelijke laag om includes te ontdekken.
- Bouw een Figment-grafiek uit de ontdekte configuratiebestanden.
- Voeg de
ConfiqueEnvProvidersamen met hogere prioriteit dan bestanden. - Voeg eventueel toepassingsspecifieke CLI-overrides samen.
- Extraheer een
confique-laag uit Figment. - Pas
confique-codestandaarden toe. - Valideer en bouw het uiteindelijke schema.
load_config en load_config_with_figment voeren stappen 1-5 en 7-9 uit.
Stap 6 is toepassingsspecifiek omdat deze crate niet kan afleiden hoe een
CLI-vlag naar een schemaveld mappt.
Bestandsformaten
De runtimebestandsprovider wordt gekozen uit de extensie van het configuratiepad:
.yamlen.ymlgebruiken YAML..tomlgebruikt TOML..jsonen.json5gebruiken JSON.- onbekende of ontbrekende extensies gebruiken YAML.
Sjabloongeneratie gebruikt nog steeds de template-renderers van confique voor YAML, TOML en JSON5-compatibele uitvoer.
Include-prioriteit
De high-level loader voegt bestandsproviders zo samen dat geinclude bestanden lagere prioriteit hebben dan het bestand dat ze include. Het rootconfiguratie- bestand heeft de hoogste bestandsprioriteit.
Omgevingsvariabelen hebben hogere prioriteit dan alle configuratiebestanden.
confique-defaults worden alleen gebruikt voor waarden die niet door
runtimeproviders worden geleverd.
Wanneer CLI-overrides na build_config_figment worden samengevoegd, is de
volledige prioriteit:
command-line overrides
> environment variables
> config files
> confique code defaults
De commandoregelsyntaxis wordt niet door rust-config-tree gedefinieerd. Een
vlag zoals --server-port kan server.port overschrijven als de toepassing die
geparsede waarde in een geneste geserialiseerde provider mappt. Een gestippelde
syntaxis zoals --server.port of a.b.c bestaat alleen als de toepassing die
implementeert.
Dit betekent dat CLI-prioriteit alleen geldt voor sleutels die aanwezig zijn in de overrideprovider van de toepassing. Gebruik dit voor operationele waarden die vaak voor een enkele run worden gewijzigd. Laat duurzame configuratie in bestanden staan.
#![allow(unused)]
fn main() {
use figment::providers::Serialized;
use serde::Serialize;
use rust_config_tree::{build_config_figment, load_config_from_figment};
#[derive(Debug, Serialize)]
struct CliOverrides {
#[serde(skip_serializing_if = "Option::is_none")]
server: Option<CliServerOverrides>,
}
#[derive(Debug, Serialize)]
struct CliServerOverrides {
#[serde(skip_serializing_if = "Option::is_none")]
port: Option<u16>,
}
let cli_overrides = CliOverrides {
server: Some(CliServerOverrides { port: Some(9000) }),
};
let figment = build_config_figment::<AppConfig>("config.yaml")?
.merge(Serialized::defaults(cli_overrides));
let config = load_config_from_figment::<AppConfig>(&figment)?;
let _ = config;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Omgevingsvariabelen
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Namen van omgevingsvariabelen worden in het schema gedeclareerd met confique:
#![allow(unused)]
fn main() {
#[derive(Debug, Config)]
struct DatabaseConfig {
#[config(env = "APP_DATABASE_URL")]
url: String,
#[config(default = 16)]
#[config(env = "APP_DATABASE_POOL_SIZE")]
pool_size: u32,
}
}
rust-config-tree leest die namen uit confique::Config::META en bouwt een
Figment-provider die elke omgevingsvariabele naar het exacte veldpad mappt.
Gebruik geen delimiter-gebaseerde Figment-omgevingsmapping voor deze crate:
#![allow(unused)]
fn main() {
// Do not use this pattern for rust-config-tree schemas.
Env::prefixed("APP_").split("_")
Env::prefixed("APP_").split("__")
}
split("_") behandelt underscores als scheidingstekens voor geneste sleutels.
Daardoor wordt APP_DATABASE_POOL_SIZE een pad zoals database.pool.size, wat
botst met Rust-veldnamen zoals pool_size.
Met ConfiqueEnvProvider is deze mapping expliciet:
APP_DATABASE_POOL_SIZE -> database.pool_size
Enkele underscores blijven onderdeel van de naam van de omgevingsvariabele. Figment raadt de nestingregel niet.
Dotenv laden
Voordat runtimeproviders worden geevalueerd, zoekt de loader naar een .env-
bestand door omhoog te lopen vanaf de directory van het rootconfiguratiebestand.
Bestaande procesomgevingsvariabelen blijven behouden. Waarden uit .env vullen
alleen ontbrekende omgevingsvariabelen aan.
Voorbeeld:
APP_SERVER_PORT=9000
APP_DATABASE_POOL_SIZE=64
Deze variabelen overschrijven configuratiebestandswaarden wanneer het schema
passende #[config(env = "...")]-attributen declareert.
Waarden parsen
De bridgeprovider laat Figment omgevingswaarden parsen. Hij roept de
parse_env-hooks van confique niet aan. Houd complexe waarden in
configuratiebestanden tenzij de Figment-syntaxis voor omgevingswaarden goed bij
het type past.
Brontracking
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Gebruik load_config_with_figment om de Figment-grafiek te behouden die door
runtime laden is gebruikt:
#![allow(unused)]
fn main() {
use rust_config_tree::load_config_with_figment;
let (config, figment) = load_config_with_figment::<AppConfig>("config.yaml")?;
let _ = config;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
De geretourneerde Figment-waarde kan bronvragen voor runtimewaarden beantwoorden:
#![allow(unused)]
fn main() {
if let Some(metadata) = figment.find_metadata("database.pool_size") {
let source = metadata.interpolate(
&figment::Profile::Default,
&["database", "pool_size"],
);
println!("database.pool_size came from {source}");
}
}
Voor waarden die door ConfiqueEnvProvider worden geleverd, retourneert
interpolatie de native naam van de omgevingsvariabele die in het schema is
gedeclareerd:
database.pool_size came from APP_DATABASE_POOL_SIZE
TRACE-events
De loader emitteert brontrackingevents met tracing::trace!. Dit gebeurt
alleen wanneer TRACE is ingeschakeld:
#![allow(unused)]
fn main() {
use rust_config_tree::{load_config_with_figment, trace_config_sources};
let (config, figment) = load_config_with_figment::<AppConfig>("config.yaml")?;
// If the tracing subscriber is initialized after config loading, emit the
// same source events again after installing the subscriber.
trace_config_sources::<AppConfig>(&figment);
let _ = config;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Elk event gebruikt het target rust_config_tree::config en bevat:
config_key: de gestippelde configuratiesleutel.source: de gerenderde bronmetadata.
Waarden die alleen uit confique-defaults komen, hebben geen Figment-
runtime-metadata. Ze worden gerapporteerd als confique default or unset optional field.
Sjabloongeneratie
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Sjablonen worden gegenereerd uit hetzelfde confique-schema dat runtime wordt
gebruikt. confique rendert de daadwerkelijke sjablooninhoud, inclusief
doccomments, defaults, verplichte velden en gedeclareerde omgevingsvariabelen.
Gebruik write_config_templates:
#![allow(unused)]
fn main() {
use rust_config_tree::write_config_templates;
write_config_templates::<AppConfig>("config.yaml", "config.example.yaml")?;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Genereer Draft 7 JSON Schemas voor de rootconfiguratie en gesplitste geneste secties:
#![allow(unused)]
fn main() {
use rust_config_tree::write_config_schemas;
write_config_schemas::<AppConfig>("schemas/myapp.schema.json")?;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Markeer een genest veld met #[schemars(extend("x-tree-split" = true))]
wanneer het als eigen *.yaml-sjabloon en eigen
<section>.schema.json-schema moet worden gegenereerd. Ongemarkeerde geneste
velden blijven in het oudersjabloon en het ouderschema.
Markeer een leafveld met #[schemars(extend("x-env-only" = true))] wanneer de waarde alleen uit omgevingsvariabelen mag komen. Gegenereerde sjablonen en JSON Schemas laten env-only velden weg, en lege bovenliggende objecten die daardoor overblijven worden verwijderd.
Gegenereerde schema’s laten required-constraints weg. IDE’s kunnen nog steeds
completion bieden, maar gedeeltelijke bestanden zoals log.yaml
rapporteren geen ontbrekende rootvelden. Het rootschema vult alleen velden aan
die in het rootbestand thuishoren; gesplitste sectievelden worden daar weggelaten
en door hun eigen sectieschema’s aangevuld. Aanwezige velden kunnen nog steeds
basale editorcontroles krijgen, zoals type-, enum- en onbekende-eigenschapcontroles
die door het gegenereerde schema worden ondersteund. Gegenereerde
*.schema.json-bestanden bepalen niet of een concrete veldwaarde geldig is voor
de toepassing. Veldwaardevalidatie moet in code worden geimplementeerd met
#[config(validate = Self::validate)]; load_config en config-validate
voeren die runtimevalidatie uit.
Koppel die schema’s vanuit gegenereerde TOML-, YAML-, JSON- en JSON5-sjablonen:
#![allow(unused)]
fn main() {
use rust_config_tree::write_config_templates_with_schema;
write_config_templates_with_schema::<AppConfig>(
"config.toml",
"config.example.toml",
"schemas/myapp.schema.json",
)?;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
TOML- en YAML-rootsjablonen koppelen het rootschema en vullen geen velden van
gesplitste kindsecties aan. Gesplitste sectie-YAML-sjablonen koppelen hun
sectieschema. JSON- en JSON5-sjablonen krijgen een rootveld $schema dat
VS Code kan herkennen. VS Code json.schemas blijft een alternatieve
koppelingsroute.
Het uitvoerformaat wordt afgeleid uit het uitvoerpad:
.yamlen.ymlgenereren YAML..tomlgenereert TOML..jsonen.json5genereren JSON5-compatibele sjablonen.- onbekende of ontbrekende extensies genereren YAML.
Schemabindingen
Met een schemapad van schemas/myapp.schema.json gebruiken gegenereerde
rootsjablonen:
#:schema ./schemas/myapp.schema.json
# yaml-language-server: $schema=./schemas/myapp.schema.json
Gegenereerde sectiesjablonen koppelen sectieschema’s:
# log.yaml
# yaml-language-server: $schema=./schemas/log.schema.json
Gegenereerde JSON- en JSON5-sjablonen schrijven een rootveld $schema dat
VS Code herkent. Editorinstellingen blijven optioneel:
{
"json.schemas": [
{
"fileMatch": [
"/config.json",
"/config.*.json"
],
"url": "./schemas/myapp.schema.json"
}
]
}
Selectie van sjabloonbron
Sjabloongeneratie kiest de bronboom in deze volgorde:
- Bestaand configuratiepad.
- Bestaand uitvoersjabloonpad.
- Uitvoerpad behandeld als een nieuwe lege sjabloonboom.
Daardoor kan een project sjablonen bijwerken vanuit huidige configuratiebestanden, een bestaande sjabloonset bijwerken of een nieuwe sjabloonset maken vanuit alleen het schema.
Gespiegelde include-bomen
Als het bronbestand includes declareert, spiegelen gegenereerde sjablonen die include-paden onder de uitvoerdirectory.
# config.yaml
include:
- server.yaml
Het genereren van config.example.yaml schrijft:
config.example.yaml
server.yaml
Relatieve include-doelen worden gespiegeld onder de parentdirectory van het uitvoerbestand. Absolute include-doelen blijven absoluut.
Opt-in sectiesplitsing
Wanneer een bronbestand geen includes heeft, kan de crate include-doelen
afleiden uit geneste schemaselecties gemarkeerd met x-tree-split. Voor een schema met een gemarkeerde server-sectie
kan een leeg rootsjabloon bijvoorbeeld produceren:
config.example.yaml
server.yaml
Het rootsjabloon krijgt een include-blok en server.yaml bevat alleen
de server-sectie. Geneste secties worden alleen recursief gesplitst wanneer die velden ook x-tree-split dragen.
IDE-completions
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Gegenereerde JSON Schemas kunnen worden gebruikt door TOML-, YAML-, JSON- en
JSON5-configuratiebestanden. Ze worden gegenereerd uit hetzelfde Rust-type dat
door confique wordt gebruikt:
#![allow(unused)]
fn main() {
use confique::Config;
use schemars::JsonSchema;
#[derive(Debug, Config, JsonSchema)]
struct AppConfig {
#[config(nested)]
#[schemars(extend("x-tree-split" = true))]
server: ServerConfig,
}
}
Genereer ze met:
#![allow(unused)]
fn main() {
use rust_config_tree::write_config_schemas;
write_config_schemas::<AppConfig>("schemas/myapp.schema.json")?;
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Dit schrijft het rootschema en sectieschema’s zoals
schemas/server.schema.json. Gegenereerde schema’s laten required-
constraints weg, zodat completion werkt voor gedeeltelijke configuratiebestanden
zonder diagnostics voor ontbrekende velden. Het rootschema laat geneste
sectie-eigenschappen weg, zodat completion voor kindsecties alleen beschikbaar
is in bestanden die het passende sectieschema koppelen.
Velden gemarkeerd met x-env-only worden uit gegenereerde schemas weggelaten, zodat IDEs geen secrets of andere waarden voorstellen die alleen uit omgevingsvariabelen mogen komen.
IDE-schema’s zijn voor completion en basale editorcontroles, zoals type-, enum-
en onbekende-eigenschapcontroles die door het gegenereerde schema worden
ondersteund. Ze bepalen niet of een concrete veldwaarde geldig is voor de
toepassing. Veldwaardevalidatie moet in code worden geimplementeerd met
#[config(validate = Self::validate)] en wordt uitgevoerd via load_config of
config-validate. Verplichte velden en uiteindelijke samengevoegde
configuratievalidatie gebruiken ook die runtimepaden.
TOML
TOML-bestanden moeten het schema koppelen met een #:schema-directive bovenaan
het bestand:
#:schema ./schemas/myapp.schema.json
[server]
bind = "0.0.0.0"
port = 3000
Gebruik geen rootveld $schema = "..." in TOML. Het wordt echte
configuratiedata en kan runtime-deserialisatie beinvloeden.
write_config_templates_with_schema voegt de #:schema-directive automatisch
toe voor TOML-sjablonen.
YAML
YAML-bestanden moeten de YAML Language Server-modeline gebruiken:
# yaml-language-server: $schema=./schemas/myapp.schema.json
server:
bind: 0.0.0.0
port: 3000
write_config_templates_with_schema voegt deze modeline automatisch toe voor
YAML-sjablonen. Gesplitste YAML-sjablonen koppelen hun sectieschema, bijvoorbeeld
log.yaml koppelt ./schemas/log.schema.json.
JSON
JSON- en JSON5-bestanden kunnen een schema koppelen met een rootveld $schema. write_config_templates_with_schema voegt dit automatisch toe aan gegenereerde JSON- en JSON5-sjablonen:
{
"$schema": "./schemas/myapp.schema.json"
}
Editorinstellingen blijven nuttig wanneer een project geen binding in het bestand wil:
{
"json.schemas": [
{
"fileMatch": [
"/config.json",
"/config.*.json",
"/deploy/*.json"
],
"url": "./schemas/myapp.schema.json"
}
]
}
YAML kan ook via VS Code-instellingen worden gekoppeld:
{
"yaml.schemas": {
"./schemas/myapp.schema.json": [
"config.yaml",
"config.*.yaml",
"deploy/*.yaml"
]
}
}
De uiteindelijke indeling is:
schemas/myapp.schema.json:
Alleen velden van het rootbestand
schemas/server.schema.json:
Schema voor de sectie server
config.toml:
#:schema ./schemas/myapp.schema.json
config.yaml:
# yaml-language-server: $schema=./schemas/myapp.schema.json
server.yaml:
# yaml-language-server: $schema=./schemas/server.schema.json
config.json:
"$schema": "./schemas/myapp.schema.json"
Referenties:
CLI-integratie
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
ConfigCommand biedt herbruikbare clap-subcommands:
config-templateconfig-schemaconfig-validatecompletionsinstall-completionsuninstall-completions
Deze ingebouwde subcommands staan los van toepassingsspecifieke configuratie- overridevlaggen. Voeg configuratie-overridevlaggen als Figment-providers samen in het runtime-laadpad.
Configuratie-overridevlaggen blijven onderdeel van de CLI van de consumerende
toepassing. Hun namen hoeven niet overeen te komen met gestippelde
configuratiepaden. De toepassing kan bijvoorbeeld --server-port parsen en
naar de geneste configuratiesleutel server.port mappen. Alleen vlaggen die de
toepassing in CliOverrides mappt, beinvloeden configuratiewaarden.
Flatten het in een toepassingsopdrachtenenum:
- Behoud het eigen
Parser-type van de toepassing. - Behoud de eigen
Subcommand-enum van de toepassing. - Voeg
#[command(flatten)] Config(ConfigCommand)aan die enum toe. - Clap breidt de geflattende
ConfigCommand-varianten uit naar hetzelfde opdracht niveau als de eigen varianten van de toepassing. - Match de variant
Config(command)en geef die door aanhandle_config_command.
use std::path::PathBuf;
use clap::{Parser, Subcommand};
use confique::Config;
use schemars::JsonSchema;
use rust_config_tree::{ConfigCommand, ConfigSchema, handle_config_command, load_config};
#[derive(Debug, Config, JsonSchema)]
struct AppConfig {
#[config(default = [])]
include: Vec<PathBuf>,
}
impl ConfigSchema for AppConfig {
fn include_paths(layer: &<Self as Config>::Layer) -> Vec<PathBuf> {
layer.include.clone().unwrap_or_default()
}
}
#[derive(Debug, Parser)]
#[command(name = "demo")]
struct Cli {
#[arg(long, default_value = "config.yaml")]
config: PathBuf,
#[command(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
enum Command {
Run,
#[command(flatten)]
Config(ConfigCommand),
}
fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let cli = Cli::parse();
match cli.command {
Command::Run => {
let config = load_config::<AppConfig>(&cli.config)?;
println!("{config:#?}");
}
Command::Config(command) => {
handle_config_command::<Cli, AppConfig>(command, &cli.config)?;
}
}
Ok(())
}
Configuratiesjablonen
demo config-template
De opdracht schrijft sjablonen onder config/<root_config_name>/. Als
--output een pad ontvangt, wordt alleen de bestandsnaam gebruikt. Als geen
uitvoerbestandsnaam is opgegeven, schrijft de opdracht
config/<root_config_name>/<root_config_name>.example.yaml. Voeg
--schema schemas/myapp.schema.json toe om gegenereerde TOML-, YAML-, JSON- en
JSON5-sjablonen te koppelen aan gegenereerde JSON Schemas. Gesplitste
YAML-sjablonen koppelen het passende sectieschema. JSON- en JSON5-sjablonen
krijgen een $schema-veld dat VS Code herkent. De opdracht schrijft ook het
root- en de sectieschema’s naar het gekozen schemapad.
demo config-template --output app_config.example.toml --schema schemas/myapp.schema.json
Genereer root- en sectie-JSON Schemas:
demo config-schema
Zonder --output schrijft config-schema het rootschema naar
config/<root_config_name>/<root_config_name>.schema.json.
Valideer de volledige runtimeconfiguratieboom:
demo config-validate
Gegenereerde editorschema’s vermijden bewust diagnostics voor verplichte velden
in gesplitste bestanden. config-validate laadt includes, past defaults toe en
voert uiteindelijke confique-validatie uit, inclusief validators die met
#[config(validate = Self::validate)] zijn gedeclareerd. Gegenereerde
*.schema.json-bestanden blijven voor IDE-completion en basale editorcontroles,
niet voor veldwaardelegaliteit. Het print Configuration is ok wanneer de
validatie slaagt.
Shellcompletions
Print completions naar stdout:
demo completions zsh
Installeer completions:
demo install-completions zsh
Verwijder completions:
demo uninstall-completions zsh
De installer ondersteunt Bash, Elvish, Fish, PowerShell en Zsh. Hij schrijft het completionbestand onder de home-directory van de gebruiker en werkt het shellstartbestand bij voor shells die dat vereisen.
Voordat een bestaand shellstartbestand zoals ~/.zshrc, ~/.bashrc, een
Elvish rc-bestand of een PowerShell-profiel wordt gewijzigd, schrijft de
opdracht een backup naast het originele bestand:
<rc-file>.backup.by.<program-name>.<timestamp>
Voorbeelden
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
De repository bevat uitvoerbare voorbeelden voor het laden van configuratiebomen, CLI-overrides, ingebouwde configuratieopdrachten, sjabloongeneratie en de lagere tree-API.
Lees de voorbeeldenindex van de repository:
Voer voorbeelden uit vanuit de repositoryroot:
cargo run --example basic_loading
cargo run --example cli_overrides -- --server-port 9000
cargo run --example config_commands -- config-template
cargo run --example config_commands -- config-schema
cargo run --example config_commands -- config-validate
cargo run --example generate_templates
cargo run --example tree_api
Tree API
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Gebruik de lagere tree-API wanneer de toepassing geen confique gebruikt, of
wanneer directe toegang tot traversalresultaten nodig is.
#![allow(unused)]
fn main() {
use std::{
fs,
io,
path::{Path, PathBuf},
};
use rust_config_tree::{ConfigSource, load_config_tree};
fn load_source(path: &Path) -> io::Result<ConfigSource<String>> {
let content = fs::read_to_string(path)?;
let includes = content
.lines()
.filter_map(|line| line.strip_prefix("include: "))
.map(PathBuf::from)
.collect();
Ok(ConfigSource::new(content, includes))
}
let tree = load_config_tree("config.yaml", load_source)?;
for node in tree.nodes() {
println!("{}", node.path().display());
}
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
}
Traversalregels
De tree-loader:
- normaliseert bronpaden lexicaal;
- weigert lege include-paden;
- lost relatieve includes op vanuit het bestand dat ze declareerde;
- behoudt absolute include-paden;
- detecteert recursieve include-cycli;
- slaat bestanden over die al via een andere include-tak zijn geladen.
ConfigTreeOptions kan sibling-include-traversal omkeren:
#![allow(unused)]
fn main() {
use rust_config_tree::{ConfigTreeOptions, IncludeOrder};
let options = ConfigTreeOptions::default().include_order(IncludeOrder::Reverse);
let _ = options;
}
Padhulpen
De padhulpen zijn alleen lexicaal. Ze lossen geen symbolische links op en vereisen niet dat paden bestaan:
absolutize_lexical(path)normalize_lexical(path)resolve_include_path(parent_path, include_path)
GitHub Pages
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
Deze repository publiceert de handleiding met mdBook en GitHub Pages.
Elke taalhandleiding is een zelfstandig mdBook-project. Elke taal heeft een
eigen SUMMARY.md, zodat de linkerzijbalk alleen pagina’s voor de huidige taal
bevat:
manual/
en/
book.toml
SUMMARY.md
introduction.md
quick-start.md
...
zh/
book.toml
SUMMARY.md
introduction.md
quick-start.md
...
ja/
book.toml
SUMMARY.md
introduction.md
quick-start.md
...
ko/
fr/
de/
es/
pt/
sv/
fi/
nl/
Bouw lokaal met:
scripts/publish-pages.sh
De gegenereerde site wordt geschreven naar:
target/mdbook
Publicatieworkflow
De workflow in .github/workflows/pages.yml draait bij pushes naar main en
bij handmatige dispatch. Hij:
- Checkt de repository uit.
- Installeert mdBook.
- Draait
scripts/publish-pages.sh. - Uploadt
target/mdbookals Pages-artefact. - Deployt het artefact naar GitHub Pages.
De gepubliceerde URL is:
https://developerworks.github.io/rust-config-tree/
Crate-release
Voor de volledige flow van commit, push, Pages-deploy en crate-publicatie:
scripts/release.sh --execute --message "Release 0.1.3"
Gebruik de crate-releasehelper vanuit de repositoryroot:
scripts/publish-crate.sh
De standaardmodus voert controles en cargo publish --dry-run uit. Om naar
crates.io te publiceren nadat de controles slagen. Als de huidige versie al op
crates.io bestaat, verhoogt het script automatisch de patchversie:
scripts/publish-crate.sh --execute
Scriptgebruik wordt samengevat in scripts/README.md.