Attribute Macro config
#[config]Expand description
Define a configuration type.
§Example
use pavex::config;
#[config(key = "pool")]
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}§Guide
Check out the “Configuration” section of Pavex’s guide for a thorough introduction to configuration in Pavex applications.
§Import
Use Blueprint::config or Blueprint::import to add the newly-defined configuration type
to your application.
§Arguments
The sections below provide an exhaustive list of all the arguments and flags supported by the config macro:
| Name | Kind | Required |
|---|---|---|
key | Argument | Yes |
default_if_missing | Flag | No |
include_if_unused | Flag | No |
never_clone | Flag | No |
§key
The config macro expects a key argument.
key will be used as the name of the corresponding field in the
generated ApplicationConfig struct.
The provided key must satisfy a few constraints:
- It can’t be empty.
- It must start with a letter.
- It can only contain letters, numbers, and underscores.
- It must be unique within the application.
§Example
use pavex::config;
#[config(key = "pool")]
// 👆 The key for this configuration type.
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}§default_if_missing
By default, Pavex considers all configuration types to be required. There must be a value for each configuration key in the source we’re reading from—e.g. a YAML configuration file. If a key is missing, Pavex will return an error.
The default_if_missing flag disables this behaviour.
Pavex will invoke Default::default() to provide a default
value if the configuration key was omitted by the configuration source. No error will be raised.
default_if_missing can only be used on types that implement the Default trait.
§Example
Consider the following configuration type:
use pavex::config;
#[config(key = "pool", default_if_missing)]
// 👆 The flag
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}
impl Default for PoolConfig {
fn default() -> Self {
Self {
max_n_connections: 10,
min_n_connections: 2,
}
}
}The definition of ApplicationConfig, in the generated server SDK code, will look like this:
#[derive(serde::Deserialize, Debug, Clone)]
pub struct ApplicationConfig {
#[serde(default)]
// 👆 Tell `serde` to use the default value
// if the field is missing.
pub pool: PoolConfig,
// [..other config types..]
}Therefore, given this YAML configuration file as input,
tls:
enabled: true
# No `pool` entry!Pavex will initialize PoolConfig using its default values, rather than returning an error.
§include_if_unused
By default, Pavex will prune unused configuration types from the
final ApplicationConfig type.
The include_if_unused flag disables this behaviour.
There will always be an entry in ApplicationConfig for configuration types
marked as include_if_unused, even if their value is never accessed by any constructor,
route, or middleware.
§Example
Consider this configuration type:
use pavex::config;
#[config(key = "pool", include_if_unused)]
// 👆 The flag
#[derive(serde::Deserialize, Debug, Clone)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}The resulting ApplicationConfig will always contain an entry for PoolConfig,
even if it’s never used. In the generated server SDK code:
#[derive(Debug, Clone, serde::Deserialize)]
pub struct ApplicationConfig {
pub pool: PoolConfig,
// 👆 You'll always find this field.
// [..other config types..]
}§never_clone
By default, Pavex will invoke .clone() on configuration types if it helps to satisfy
Rust’s borrow checker.
The never_clone flag disables this behaviour:
use pavex::config;
#[config(key = "pool", never_clone)]
// 👆 The flag
#[derive(serde::Deserialize, Debug)]
pub struct PoolConfig {
pub max_n_connections: u32,
pub min_n_connections: u32,
}Pavex will report an error during the code-generation phase if cloning is required but forbidden.