Expand description
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):
- From a dotenv style file
.env.toml(a file name of your choosing) - From an environment variable
CONFIG(or a variable name of your choosing). - From mapped environments (e.g.
MY_VARIABLE => my_variable.child). - From a configuration file.
Why yet another config library?
Here are some possible alternatives to this library:
configYou want maximum flexibility.figmentYou want maximum flexibility.just-configYou want maximum flexibility.dotenvyYou just want.envsupport.env_inventoryYou just want environment variable configuration file support.
Why would you use this one?
- Small feature set.
- Minimal dependencies.
- Opinionated defaults.
.envusingTOMLwhich is a more established file format standard.- Loading config from TOML stored in a multiline environment variable.
- For large configurations with nested maps, this could be seen as a bit more legible than
MY_VARIABLE__SOMETHING_ELSE__SOMETHING_SOMETHING_ELSE. - You can also just copy text from a TOML file to use in the environment variable instead of translating it into complicated names of variables.
- For large configurations with nested maps, this could be seen as a bit more legible than
Config Struct
Firstly you need to define your struct which implements serde::de::DeserializeOwned + serde::Serialize + Default:
#[derive(serde::Serialize, serde::Deserialize, Default)]
struct Config {
config_value_1: String,
config_value_2: String,
config_child: ConfigChild
}
#[derive(serde::Serialize, serde::Deserialize, Default)]
struct ConfigChild {
config_value_3: 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:
SECRET_ENV_VAR_1="some value"
SECRET_ENV_VAR_2="some other value"
[CONFIG]
config_value_1="some value"
config_value_2="some other value"
[CONFIG.config_child]
config_value_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.
Environment Variable CONFIG
You can specify the configuration by storing it in the variable name as specified using Args::config_variable_name (CONFIG by default).
# Store a multiline string into an environment variable in bash shell.
read -r -d '' CONFIG << EOM
config_value_1="some value"
config_value_2="some other value"
[config_child]
config_value_3="some other other value"
EOM
Example
use serde::{Deserialize, Serialize};
use tempfile::tempdir;
use toml_env::{Args, initialize, Logging, TomlKeyPath};
use std::str::FromStr;
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct Config {
value_1: String,
value_2: bool,
child: Child,
}
#[derive(Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
struct Child {
value_3: i32,
value_4: u8,
value_5: String,
}
let dir = tempdir().unwrap();
let dotenv_path = dir.path().join(".env.toml");
let config_path = dir.path().join("config.toml");
// Normally you would read this from .env.toml file
std::fs::write(
&dotenv_path,
r#"
SECRET="hello-world"
[MY_CONFIG]
value_1="Something from .env.toml"
[MY_CONFIG.child]
value_3=-5
value_4=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::set_var(
"MY_CONFIG",
r#"
value_1="Something from MY_CONFIG environment"
value_2=true
"#,
);
std::env::set_var(
"VALUE_1",
"Something from Environment"
);
std::env::set_var(
"VALUE_5",
"Something from Environment"
);
// Normally you would read this from config.toml
// (or whatever name you want) file.
std::fs::write(
&config_path,
r#"
value_1="Something from config.toml"
value_2=false
[child]
value_4=45
"#,
)
.unwrap();
let config: Config = initialize(Args {
dotenv_path: &dotenv_path,
config_path: Some(&config_path),
config_variable_name: "MY_CONFIG",
logging: Logging::StdOut,
map_env: [
("VALUE_1", "value_1"),
("VALUE_5", "child.value_5"),
("VALUE_99", "does.not.exist"),
]
.into_iter()
.map(|(key, value)| {
(key, TomlKeyPath::from_str(value).unwrap())
})
})
.unwrap()
.unwrap();
assert_eq!(config.value_1, "Something from .env.toml");
assert_eq!(config.value_2, true);
assert_eq!(config.child.value_3, -5);
assert_eq!(config.child.value_4, 16);
let secret = std::env::var("SECRET").unwrap();
assert_eq!(secret, "hello-world");Changelog
See CHANGELOG.md for an account of changes to this library.
Structs
- Args as input to
initialize(). - A path to a key into a
toml::Value.
Enums
- A source of configuration.
- An error that occurs while initializing configuration.
- What method of logging for this library to use.
Constants
- Default environment variable name to use for loading configuration from. Also the same name used for the table of the configuration within the
.env.toml. - Default name for attempting to load the configuration (and environment variables) from a file.
Functions
- Initialize configuration from available sources specified in
Args.
Type Aliases
- Convenience type shorthand for
Result<T, Error>.