Crates.io | econf |
lib.rs | econf |
version | 0.3.0 |
source | src |
created_at | 2019-06-20 00:26:36.187977 |
updated_at | 2024-09-13 04:51:04.307352 |
description | Load environment variables into your struct members in one shot. |
homepage | https://github.com/YushiOMOTE/econf |
repository | https://github.com/YushiOMOTE/econf |
max_upload_size | |
id | 142235 |
size | 49,706 |
Loads environment variables into your structs in one shot.
econf
allows to override struct fields with environment variables easily. This is useful to build up applications that optionally overrides some configuration with environment variables. Here is the basic usage:
use econf::LoadEnv;
#[derive(Debug, LoadEnv)]
struct A {
x: bool,
y: u64,
}
let a = A {
x: true,
y: 42,
};
println!("Before: {:?}", a);
let a = econf::load(a, "PREFIX");
println!("After: {:?}", a);
$ ./app
Before: A { x: true, y: 42 }
After: A { x: true, y: 42 }
$ PREFIX_X=false ./app
Before: A { x: true, y: 42 }
After: A { x: false, y: 42 }
In this example,
PREFIX_X
is loaded to x
PREFIX_Y
is loaded to y
The environment variables are all upper-case with _
separated.
There are some existing crates that provide similar features but econf
is unique in the following ways:
Vec
, HashMap
and various types.bool
isize
, usize
, i8
, i16
,i32
,i64
,i128
, u8
,u16
,u32
,u64
,u128
char
, String
f32
, f64
IpAddr
,Ipv4Addr
,Ipv6Addr
,SocketAddr
,SocketAddrV4
,SocketAddrV6
NonZeroI128
,NonZeroI16
,NonZeroI32
,NonZeroI64
,NonZeroI8
,NonZeroIsize
,NonZeroU128
, NonZeroU16
,NonZeroU32
,NonZeroU64
,NonZeroU8
, NonZeroUsize
PathBuf
Vec
, HashSet
, HashMap
, Option
, BTreeMap
, BTreeSet
, BinaryHeap
, LinkedList
, VecDeque
, tuple
Since v0.3.0, econf requires enums to implement FromStr trait. Without this implementation, your program will fail to compile. While you can write the FromStr
implementation manually, you can alternatively use strum crate to automatically generate it. strum
provides several useful features, making it a generally recommended choice. See econf/examples/strum.rs for example code.
use econf::LoadEnv;
#[derive(Debug, strum::EnumString, LoadEnv)]
#[strum(serialize_all = "kebab-case")]
enum AuthMode {
ApiKey,
BasicAuth,
#[strum(ascii_case_insensitive)]
BearerToken,
#[strum(serialize = "oauth", serialize = "OAuth")]
OAuth,
JWT,
}
Nested structs are supported.
#[derive(LoadEnv)]
struct A {
v1: usize,
v2: B,
}
#[derive(LoadEnv)]
struct B {
v1: usize,
v2: usize,
}
let a = A {
v1: 1,
v2: B {
v1: 2,
v2: 3,
},
};
let a = econf::load(a, "PREFIX");
In this example,
PREFIX_V1
is loaded to a.v1
PREFIX_V2_V1
is loaded to a.v2.v1
PREFIX_V2_V2
is loaded to a.v2.v2
Fields in child structs can be specified by chaining the field names with _
as a separator.
However, there're cases that names conflict. For example,
#[derive(LoadEnv)]
struct A {
v2_v1: usize,
v2: B,
}
#[derive(LoadEnv)]
struct B {
v1: usize,
v2: usize,
}
let a = A {
v2_v1: 1,
v2: B {
v1: 2,
v2: 3,
},
};
let a = econf::load(a, "PREFIX");
Here PREFIX_V2_V1
corresponds to both a.v2_v1
and a.v2.v1
. In this case, econf
prints warning through log facade
and the value is loaded to both a.v2_v1
and a.v2.v1
.
Fields that do not implement LoadEnv or simply should not be loaded by econf can be skipped by adding the #[econf(skip)]
helper attribute:
#[derive(LoadEnv)]
struct A {
x: bool,
#[econf(skip)]
y: u64, // will not be loaded by econf
}
Load a field with the given name instead of its Rust's field name. This is helpful if the environment variable name and Rust's field name don't match:
#[derive(LoadEnv)]
struct A {
x: bool,
#[econf(rename = "ANOTHER_Y")]
y: u64, // will be loaded from an environment variable `ANOTHER_Y`
}
License: MIT