Expand description
Byre is opinionated. It is a shallow wrapper around collection of crates.
Use byre as a means to avoid bikeshedding and bootstrap programs more quickly.
It provides:
- command line parsing (via clap)
- config file generation and loading (via Doku & Figment)
- environment variable overrides for configs (via Doku)
- logging & tracing & metrics (via tracing & opentelemetry)
§Tutorial
- Start by adding byre and its peer dependencies to your Cargo.toml.
[dependencies]
byre = "0.3"
doku = "0.21"
serde = "1"
tokio = "1"
clap = { version = "4", features = ["derive"] } # Only if defining custom CLI Arguments- Create a Settings struct that will be used to hold your application settings and the telemetry settings.
use doku::Document;
use serde::Deserialize;
/// Settings container
#[derive(Document, Deserialize)]
pub struct Settings {
/// App Settings
pub application: Application,
/// Telemetry settings.
pub telemetry: byre::telemetry::TelemetrySettings,
}
#[derive(Document, Deserialize)]
pub struct Application {
/// Port to listen on
#[doku(example = "8080")]
pub listen_port: u16,
/// Hostname to listen to
#[doku(example = "localhost")]
pub listen_host: String,
/// Directory where the application databases are located
#[doku(example = "/var/db/app_dbs")]
pub application_db_dir: std::path::PathBuf,
}- Have
byrehandle the CLI argument parsing, config, and env overrides:
// Parse command line arguments. Add additional command line option that allows checking
// the config without running the server.
let service_info = byre::service_info!();
let Some(cli) = byre::cli::Cli::<Settings>::try_new(&service_info, "MYAPP_")? else {
// Config file was generated, exit successfully
return Ok(());
};
// ...- Initialize the
byretelemetry
let _telemetry = byre::telemetry::init(&service_info, &cli.config.telemetry)?;§Override config value via environment values
Environment variables can be used to override a setting from a config file.
Overrides can be nested. For example, to override the application.listen_port one would set an environment value like so, replacing the dot (.) with double underscores (__):
MYAPP_APPLICATION__LISTEN_PORT=8080 ./test_app --config ./test_app.toml§Additional Command line arguments
Create a struct that represents the Arguments you want to check for. Add clap to your dependencies and use clap::Parser for the derive macro.
use clap::Parser;
use serde::Serialize;
#[derive(Parser, Deserialize, Serialize)]
/// A NEW description, not using the one from Cargo.toml!
pub struct Arguments {
/// world peace, careful, has consequences
#[arg(short, long)]
pub enable_world_peace: bool,
}
// Parse command line arguments. Add additional command line option that allows checking
// the config without running the server.
let service_info = byre::service_info!();
let Some(cli) = byre::cli::Cli::<Settings, Arguments>::try_new(&service_info, "MYAPP_")? else {
return Ok(());
};
let _telemetry = byre::telemetry::init(&service_info, &cli.config.telemetry)?;
// Check if world peace has been enabled
if cli.args.enable_world_peace {
// yay!
}Notice that the description is overridden and there is an option to enable world peace.
❯ test_app --help
A NEW description, not using the one from Cargo.toml!
Usage: test_app [OPTIONS]
Options:
-e, --enable-world-peace world peace, careful, has consequences
-c, --config <config> Specifies the toml config file to run the service with
-g, --generate <generate> Generates a new default toml config file for the service
-h, --help Print help
-V, --version Print version§Examples
There is a full example in the source tree.
Modules§
- cli
- Command Line Interface Tools
- config
- Configuration File Handling
- telemetry
- Telemetry for Rust Applications
Macros§
- service_
info - Creates
ServiceInfofrom the information inCargo.tomlmanifest of the service.
Structs§
- Service
Info - Service information collected from the build.
Enums§
- Error
- Errors that can occur during byre operations.