toml-env
A simple configuration library using toml
.
This library is designed to load a configuration for an application at startup using the initialize()
function. The configuration can be loaded (in order of preference):
.env.toml
(a file name of your choosing)CONFIG
(or a variable name of your choosing).MY_VARIABLE => my_variable.child
).Here are some possible alternatives to this library:
config
You want maximum flexibility.figment
You want maximum flexibility.just-config
You want maximum flexibility.dotenvy
You just want .env
support.env_inventory
You just want environment variable configuration file support.Why would you use this one?
.env
using TOML
which is a more established file format standard.MY_VARIABLE => child.child.config
) in a json pointer style (full syntax is not supported).MY_APP__PARENT__CHILD => parent.child
)MY_VARIABLE__SOMETHING_ELSE__SOMETHING_SOMETHING_ELSE
.Firstly you need to define your struct which implements serde::de::DeserializeOwned
+ serde::Serialize
+ Default
:
```rust
struct Config { configvalue1: String, configvalue2: String, config_child: ConfigChild }
struct ConfigChild { configvalue3: String, } ```
.env.toml
Initally configuration will attempted to be loaded from a file named .env.toml
by default. You can elect to customize the name of this file. The format of this file is as follows:
```toml SECRETENVVAR1="some value" SECRETENVVAR2="some other value"
[CONFIG] configvalue1="some value" configvalue2="some other value"
[CONFIG.configchild] configvalue_3="some other other value" ```
Environment variables for the application can be set using the top level keys in the file (e.g. SECRET_ENV_VAR_1
).
The configuration can be loaded from a subset of this file in CONFIG
. The CONFIG
key will be the name from the Args::config_variable_name
which is CONFIG
by default.
CONFIG
You can specify the configuration by storing it in the variable name as specified using Args::config_variable_name
(CONFIG
by default).
```bash
read -r -d '' CONFIG << EOM configvalue1="some value" configvalue2="some other value"
[configchild] configvalue_3="some other other value" EOM ```
CONFIG
VariableA simple example loading configuration from CONFIG
, using the default settings.
```rust use serde::{Deserialize, Serialize}; use toml_env::{initialize, Args};
struct Config { value1: String, value2: bool, }
// Normally you may choose set this from a shell script or some // other source in your environment (docker file or server config file). std::env::setvar( "CONFIG", r#" value1="Something from CONFIG environment" value_2=true "#, );
let config: Config = initialize(Args::default()) .unwrap() .unwrap();
asserteq!(config.value1, "Something from CONFIG environment"); asserteq!(config.value2, true); ```
A simple demonstration of the custom environment variable mappings:
```rust use serde::{Deserialize, Serialize}; use toml_env::{Args, initialize, TomlKeyPath}; use std::str::FromStr;
struct Config { value1: String, value2: bool, }
// Normally you may choose set this from a shell script or some // other source in your environment (docker file or server config file). std::env::setvar("VALUE1", "Hello World"); std::env::setvar("VALUE2", "true");
let config: Config = initialize(Args { mapenv: [ ("VALUE1", "value1"), ("VALUE2", "value2"), ] .intoiter() .map(|(key, value)| { (key, TomlKeyPath::from_str(value).unwrap()) }).collect(), ..Args::default() }) .unwrap() .unwrap();
asserteq!(config.value1, "Hello World"); asserteq!(config.value2, true); ```
A simple demonstration of the automatic environment variable mappings:
```rust use serde::{Deserialize, Serialize}; use toml_env::{Args, initialize, AutoMapEnvArgs};
// NOTE: the deny_unknown_fields
can be used to reject
// mappings which don't conform to the current spec.
struct Config { value1: String, value2: bool, }
// Normally you may choose set this from a shell script or some // other source in your environment (docker file or server config file). std::env::setvar("CONFIGVALUE1", "Hello World"); std::env::setvar("CONFIGVALUE2", "true");
let config: Config = initialize(Args { automapenv: Some(AutoMapEnvArgs::default()), // The default prefix is CONFIG. // In practice you would usually use a custom prefix: // prefix: Some("MY_APP"), ..Args::default() }) .unwrap() .unwrap();
asserteq!(config.value1, "Hello World"); asserteq!(config.value2, true); ```
.env.toml
FileA simple example loading configuration and environment variables from .env.toml
, using the default settings.
```rust use serde::{Deserialize, Serialize}; use toml_env::{Args, initialize};
struct Config { value1: String, value2: bool, }
let dir = tempfile::tempdir().unwrap(); std::env::setcurrentdir(&dir).unwrap(); let dotenv_path = dir.path().join(".env.toml");
// Normally you would read this from .env.toml file std::fs::write( &dotenvpath, r#" OTHERVARIABLE="hello-world" [CONFIG] value1="Something from .env.toml" value2=true "#, ) .unwrap();
let config: Config = initialize(Args::default()) .unwrap() .unwrap();
asserteq!(config.value1, "Something from .env.toml"); asserteq!(config.value2, true);
let secret = std::env::var("OTHERVARIABLE").unwrap(); asserteq!(secret, "hello-world"); ```
A more complex example demonstrating all the features.
```rust use serde::{Deserialize, Serialize}; use tempfile::tempdir; use toml_env::{Args, initialize, Logging, TomlKeyPath, AutoMapEnvArgs}; use std::str::FromStr;
struct Config { value1: String, value2: bool, child: Child, }
struct Child { value3: i32, value4: u8, value5: String, value6: String, }
let dir = tempdir().unwrap(); let dotenvpath = dir.path().join(".env.toml"); let configpath = dir.path().join("config.toml");
// Normally you would read this from .env.toml file std::fs::write( &dotenvpath, r#" SECRET="hello-world" [MYCONFIG] value1="Something from .env.toml" [MYCONFIG.child] value3=-5 value4=16 "#, ) .unwrap();
// Normally you may choose set this from a shell script or some // other source in your environment (docker file or server config file). std::env::setvar( "MYCONFIG", r#" value1="Something from MYCONFIG environment" value_2=true "#, );
std::env::setvar( "VALUE1", "Something from Environment" ); std::env::setvar( "VALUE5", "Something from Environment" ); std::env::setvar( "MYAPPCHILDVALUE_6", "Something from Environment" );
// Normally you would read this from config.toml // (or whatever name you want) file. std::fs::write( &configpath, r#" value1="Something from config.toml" value2=false [child] value4=45 "#, ) .unwrap();
let config: Config = initialize(Args { dotenvpath: &dotenvpath, configpath: Some(&configpath), configvariablename: "MYCONFIG", logging: Logging::StdOut, mapenv: [ ("VALUE1", "value1"), ("VALUE5", "child.value5"), ("VALUE99", "does.not.exist"), ] .intoiter() .map(|(key, value)| { (key, TomlKeyPath::fromstr(value).unwrap()) }).collect(), automapenv: Some(AutoMapEnvArgs { divider: "", prefix: Some("MYAPP"), transform: Box::new(|name| name.to_lowercase()), }) }) .unwrap() .unwrap();
asserteq!(config.value1, "Something from .env.toml"); asserteq!(config.value2, true); asserteq!(config.child.value3, -5); asserteq!(config.child.value4, 16);
let secret = std::env::var("SECRET").unwrap(); assert_eq!(secret, "hello-world"); ```
See CHANGELOG.md for an account of changes to this library.