Crate serde_vars

Crate serde_vars 

Source
Expand description

Conveniently expose (environment) variables to your serde based data structures, like configurations.

The main goal of this library is to allow for a very simple but yet powerful mechanism of dynamically loading single configuration values from (environment) variables. It is ideal, when you need to include sensitive values in configurations, but don’t want to or can’t (e.g. due to repeated or dynamic values) setup manual environment mappings at compile time.

By implementing a serde::de::Deserializer, this crate works independently of the serialization format used and with only a few lines of modifications for any configuration.

§Example

User provided configuration file:

{
    "redis": {
        "host": "${REDIS_HOST}",
        "port": "${REDIS_PORT}"
    }
}

The configuration file contains the variables, no need to decide on variable mappings at compile time.

#[derive(Debug, serde::Deserialize)]
struct Config {
    redis: Redis,
}

#[derive(Debug, serde::Deserialize)]
struct Redis {
    host: std::net::Ipv4Addr,
    port: u16,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config_path = std::env::args()
        .nth(1)
        .unwrap_or_else(|| "config.json".to_owned());

    let config = std::fs::read_to_string(&config_path)?;

    let mut source = serde_vars::EnvSource::default();

    // Before: `let config: Config = serde_json::from_str(&config)?`.
    // Now:
    let mut de = serde_json::Deserializer::from_str(&config);
    let config: Config = serde_vars::deserialize(&mut de, &mut source)?;

    println!("{config:#?}");

    Ok(())
}

§String based Lookups

serde-vars comes packaged with builtin variable sources for environment variables (EnvSource), hash maps (MapSource) as well as a generic string based source (StringSource).

In order to guarantee a consistent parsing behaviour, the StringSource and all of its dependent implementations (like EnvSource) enforce the following format for all values:

  • true and false are always interpreted as a bool.
  • Any positive integer is parsed as a u64.
  • Any negative integer is parsed as a i64.
  • Any floating point value is parsed as a f64.
  • Everything else is parsed as a string. In order to be able to specify numbers as strings, the source recognizes arbitrary values wrapped in " as a string. For example "123" is parsed as the literal string 123.

For more details read the StringSource documentation.

§File based Lookups

Since 0.3 a FileSource has been added, it functions very similar to a string based source, but has slightly different semantics when it comes to parsing and allows loading arbitrary binary data.

§Alternatives

Variable expansion is limited to primitive types and not supported for nested data structures, this is currently by design. The intention of this library is not to provide another generic abstraction layer for configurations. If you are looking for a much more powerful mechanism to load and layer serde based configurations, you should take a look at figment instead.

Re-exports§

pub use self::source::EnvSource;
pub use self::source::FileSource;
pub use self::source::MapSource;
pub use self::source::StringSource;

Modules§

source
Dynamic variable expansion.

Structs§

Deserializer
A deserializer which substitutes strings with values provided from a Source.

Functions§

deserialize
Entry point. See crate documentation for an example.