Merge pull request #31 from pleshevskiy/doc

doc: rewrite documentation
This commit is contained in:
Dmitriy Pleshevskiy 2022-07-24 15:54:00 +00:00 committed by GitHub
commit c71ca757d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 190 additions and 1466 deletions

587
Cargo.lock generated
View File

@ -2,186 +2,11 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
[[package]]
name = "cast"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"bitflags",
"textwrap",
"unicode-width",
]
[[package]]
name = "criterion"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f"
dependencies = [
"atty",
"cast",
"clap",
"criterion-plot",
"csv",
"itertools",
"lazy_static",
"num-traits",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_cbor",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876"
dependencies = [
"cast",
"itertools",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"once_cell",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "csv"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr",
"csv-core",
"itoa 0.4.8",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
dependencies = [
"memchr",
]
[[package]]
name = "either"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be"
[[package]]
name = "enve"
version = "1.1.1"
version = "0.1.0"
dependencies = [
"criterion",
"estring",
"lazy_static",
]
[[package]]
@ -189,413 +14,3 @@ name = "estring"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72ea7e904ef7cb950eee02f9332b6a5c24c33bebeca6c027651b04f6c20658d9"
[[package]]
name = "half"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "itertools"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
name = "js-sys"
version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "once_cell"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1"
[[package]]
name = "oorandom"
version = "11.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
name = "plotters"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9428003b84df1496fb9d6eeee9c5f8145cb41ca375eb0dad204328888832811f"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142"
[[package]]
name = "plotters-svg"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0918736323d1baff32ee0eade54984f6f201ad7e97d5cfb5d6ab4a358529615"
dependencies = [
"plotters-backend",
]
[[package]]
name = "proc-macro2"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "regex"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
version = "0.6.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "ryu"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc855a42c7967b7c369eb5860f7164ef1f6f81c20c7cc1141f2a604e18723b03"
[[package]]
name = "serde_cbor"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [
"half",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f2122636b9fe3b81f1cb25099fcf2d3f542cdb1d45940d56c713158884a05da"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7"
dependencies = [
"itoa 1.0.2",
"ryu",
"serde",
]
[[package]]
name = "syn"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "unicode-ident"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7"
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "walkdir"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
"same-file",
"winapi",
"winapi-util",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
[[package]]
name = "web-sys"
version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -1,19 +1,20 @@
[workspace]
members = []
[package]
name = "enve"
version = "1.1.1"
version = "0.1.0"
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
description = "Easy build a configs from environment variables and use it in globally."
categories = ["config", "web-programming"]
keywords = ["config", "env", "configuration", "environment", "macro"]
description = "it helps you work with environment variables and convert it to any type using only type annotations"
categories = ["config"]
keywords = ["env", "environment"]
edition = "2018"
license = "MIT"
repository = "https://github.com/pleshevskiy/enve"
homepage = "https://github.com/pleshevskiy/enve"
documentation = "https://docs.rs/enve"
readme = "../README.md"
[package.metadata]
msrv = "1.51.0"
# https://docs.rs/about
[package.metadata.docs.rs]
all-features = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -26,17 +27,9 @@ vec = ["estring/vec"]
[dependencies]
estring = "0.1"
[dev-dependencies]
lazy_static = "1.4.0"
criterion = "0.3.1"
[badges]
maintenance = { status = "actively-developed" }
# https://docs.rs/about
[package.metadata.docs.rs]
all-features = true
[[example]]
name = "calc"
required-features = ["number", "vec"]

139
README.md
View File

@ -6,24 +6,50 @@
[![Crates.io](https://img.shields.io/crates/v/enve)](https://crates.io/crates/enve)
![Crates.io](https://img.shields.io/crates/l/enve)
Easy build a configs from environment variables and use it in globally.
`enve` helps you work with environment variables and convert it to **any type**
using only **type annotations**.
We recommend you start with the [documentation].
Look at the [examples](https://github.com/pleshevskiy/enve/tree/main/examples)
to see the power!
## Motivation
All standard environment variable types are included, but `enve` under the hood
uses [estring](https://github.com/pleshevskiy/estring), so you can easily create
your own type.
I began to use rust with web programming experience where environment variables
are widely used and often there are more then 50 of them. First I looked at
already created libraries. But there it's necessary to initialise structure that
needs to be moved to each function where you need variable. It uses little bit
memory, but configuration lifetime is as long as application lifetime. Because
of it I decided to create my own library.
## Getting started
```rust
use enve::SepVec;
type MinusVec<T> = SepVec<T, '-'>;
type PlusVec<T> = SepVec<T, '+'>;
type MulVec<T> = SepVec<T, '*'>;
fn main() -> Result<(), enve::Error> {
enve::sset("E", "10+5*2-3");
let res: f32 = enve::get::<PlusVec<MinusVec<MulVec<f32>>>>("E")
.unwrap()
.iter()
.map(|p| {
p.iter()
.map(|m| m.iter().product::<f32>())
.reduce(|acc, v| acc - v)
.unwrap_or_default()
})
.sum::<f32>();
println!("result: {}", res);
Ok(())
}
```
## Installation
The MSRV is 1.39.0
Add `enve = { version = "1.0", features = ["mod"] }` as a dependency in
Add `enve = { version = "0.1", features = ["prim", "vec"] }` as a dependency in
`Cargo.toml`.
`Cargo.toml` example:
@ -35,102 +61,15 @@ version = "0.1.0"
authors = ["Me <user@rust-lang.org>"]
[dependencies]
enve = { version = "1.0", features = ["mod"] }
enve = { version = "0.1", features = ["prim", "vec"] }
```
## Basic usage
```rust
use std::env;
//use dotenv::dotenv;
enve::mod! {
DEBUG: bool => false,
#[env_name = "APP_HOST"]
HOST: String => "127.0.0.1",
database {
URL < (
"postgres://",
POSTGRES_USERNAME => "user",
":",
POSTGRES_PASSWORD => "pass",
"@",
POSTGRES_HOST => "localhost:5432",
"/",
POSTGRES_DB => "test",
),
pool {
MAX_SIZE: usize => 15,
},
},
sentry {
DSN: Option<&'static str>,
},
feature {
static CORS: bool => false,
static GRAPHQL_PLAYGROUND: bool => false,
},
}
fn main () {
// dotenv().expect("dotenv setup to be successful");
// or
env::set_var("FEATURE_CORS", "true");
config::init();
assert_eq!(config::HOST(), String::from("127.0.0.1"));
assert_eq!(config::database::URL(), String::from("postgres://user:pass@localhost:5432/test"));
assert_eq!(config::database::pool::MAX_SIZE(), 15);
assert_eq!(config::sentry::DSN(), None);
assert_eq!(config::feature::CORS(), true);
}
```
Macro is an optional feature, disabled by default. You can use this library
without macro
```rust
use std::env;
// use dotenv::dotenv;
fn main() {
// dotenv().expect("dotenv setup to be successful");
// or
env::set_var("DATABASE_URL", "postgres://127.0.0.1:5432/test");
let database_url = enve::get::<String>("DATABASE_URL").unwrap();
let new_profile: bool = enve::get("FEATURE_NEW_PROFILE").unwrap_or_default();
let articles_per_page: u32 = enve::get_or_set_default("ARTICLES_PER_PAGE", 10);
}
```
## Running tests
```bash
cargo test --all-features
```
## Available features
- **macro** - Activates `config!` macros for easy configure web application.
- **number** - Group for features: `int`, `uint` and `float`.
- **bool** - impl EnvString for `bool` type `serde_json` package). ⚠
**_DEPRECATED_**
## License
[MIT] © [pleshevskiy](https://github.com/pleshevskiy)
**MIT**. See [LICENSE](https://github.com/pleshevskiy/estring/LICENSE) to see
the full text.
## Contributors
[pleshevskiy](https://github.com/pleshevskiy) (Dmitriy Pleshevskiy) creator,
maintainer.
[documentation]: https://docs.rs/enve
[MIT]: https://github.com/icetemple/enve-rs/blob/master/LICENSE

View File

@ -8,7 +8,7 @@ Fun calculator based on environment variables
E=2*2-1-1+5*3-10 cargo run --example calc --all-features
```
Limits:
Limits (yet):
- Supports `*`, `+`, `-`
- You cannot start from a negative number. `E=-10`. Solution: start from `0`.

View File

@ -1,4 +1,4 @@
use enve::estr::SepVec;
use enve::SepVec;
type MinusVec<T> = SepVec<T, '-'>;
type PlusVec<T> = SepVec<T, '+'>;

View File

@ -2,6 +2,30 @@ use crate::error::Error;
use estring::EString;
use std::convert::TryFrom;
/// Fetches the environment variable `key` from the current process. It set value `default`
/// if environment variable `key` ins'n set. Then this function tries to parse ``EString`` to
/// expected type by annotations.
///
/// # Errors
///
/// This function will return an error if ``EString`` cannot parse substring.
///
/// This function may return an error if the environment variable's name contains
/// the equal sign character (`=`) or the NUL character.
///
/// This function will return an error if the environment variable's value is
/// not valid Unicode. If this is not desired, consider using [`var_os`].
///
/// # Examples
///
/// ```
/// let key = "doc_get_or_set";
/// match enve::get_or_set_default::<i32>(key, 10) {
/// Ok(res) => assert_eq!(res, 10),
/// Err(e) => println!("couldn't interpret {key}: {e}"),
/// }
/// ```
#[allow(clippy::needless_pass_by_value)]
pub fn get_or_set_default<R>(env_name: &str, default: R) -> Result<R, Error>
where
R: TryFrom<EString> + std::fmt::Display,
@ -12,25 +36,84 @@ where
})
}
pub fn get<R>(env_name: &str) -> Result<R, Error>
/// Fetches the environment variable `key` from the current process and then tries to parse
/// ``EString`` to expected type by annotations.
///
/// # Errors
///
/// This function will return an error if ``EString`` cannot parse substring.
///
/// This function will return an error if the environment variable isn't set.
///
/// This function may return an error if the environment variable's name contains
/// the equal sign character (`=`) or the NUL character.
///
/// This function will return an error if the environment variable's value is
/// not valid Unicode. If this is not desired, consider using [`var_os`].
///
/// # Examples
///
/// ```
/// let key = "doc_get";
/// enve::sset(key, "10");
/// match enve::get::<i32>(key) {
/// Ok(res) => assert_eq!(res, 10),
/// Err(e) => println!("couldn't interpret {key}: {e}"),
/// }
/// ```
pub fn get<R>(key: &str) -> Result<R, Error>
where
R: TryFrom<EString>,
{
sget(env_name).and_then(|v| v.parse().map_err(Error::from))
sget(key).and_then(|v| v.parse().map_err(Error::from))
}
pub fn sget(env_name: &str) -> Result<EString, Error> {
std::env::var(env_name)
.map_err(Error::from)
.map(EString::from)
/// Fetches the environment variable `key` from the current process and returns value as
/// ``EString``.
///
/// # Errors
///
/// This function will return an error if the environment variable isn't set.
///
/// This function may return an error if the environment variable's name contains
/// the equal sign character (`=`) or the NUL character.
///
/// This function will return an error if the environment variable's value is
/// not valid Unicode. If this is not desired, consider using [`var_os`].
///
/// # Examples
///
/// ```
/// let key = "HOME";
/// match enve::sget(key) {
/// Ok(val) => println!("{key}: {val:?}"),
/// Err(e) => println!("couldn't interpret {key}: {e}"),
/// }
/// ```
pub fn sget(key: &str) -> Result<EString, Error> {
std::env::var(key).map_err(Error::from).map(EString::from)
}
pub fn sset<V>(env_name: &str, value: V) -> EString
/// Sets the environment variable `key` to the value `value` for the currently running
/// process and then returns `value` as a ``EString``.
///
/// # Panics
///
/// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
/// or the NUL character `'\0'`, or when `value` contains the NUL character.
///
/// # Examples
///
/// ```
/// let estr = enve::sset("KEY", "10");
/// assert_eq!(estr.to_string(), String::from("10"));
/// ```
pub fn sset<V>(key: &str, value: V) -> EString
where
V: std::fmt::Display,
{
let val = value.to_string();
std::env::set_var(env_name, &val);
std::env::set_var(key, &val);
val.into()
}
@ -108,7 +191,7 @@ mod tests {
std::env::set_var(&en, "-10");
match get::<u32>(&en) {
Err(Error::Parse(orig)) => {
assert_eq!(orig, String::from("-10"))
assert_eq!(orig, String::from("-10"));
}
_ => unreachable!(),
};
@ -136,7 +219,7 @@ mod tests {
fn should_parse_bool_variable() {
let en = TestCase::<7>.to_string();
[
let test_cases = [
("1", true),
("y", true),
("yes", true),
@ -146,18 +229,17 @@ mod tests {
("false", false),
("f", false),
("0", false),
]
.iter()
.for_each(|(val, expected)| {
];
for (val, expected) in test_cases {
let mut en = en.clone();
en.push_str(val.as_ref());
std::env::set_var(&en, val);
match get::<bool>(&en) {
Ok(res) => assert_eq!(res, *expected),
Ok(res) => assert_eq!(res, expected),
_ => unreachable!(),
};
})
}
}
}
@ -216,7 +298,7 @@ mod tests {
std::env::set_var(&en, "1,2,3,4,5");
match get::<SepVec<i32, '+'>>(&en) {
Err(Error::Parse(orig)) => {
assert_eq!(orig, String::from("1,2,3,4,5"))
assert_eq!(orig, String::from("1,2,3,4,5"));
}
_ => unreachable!(),
};

View File

@ -20,15 +20,14 @@ pub enum Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use Error::*;
match &self {
NotPresent => f.write_str("The specified env variable was not present"),
Invalid(inner) => write!(
Error::NotPresent => f.write_str("The specified env variable was not present"),
Error::Invalid(inner) => write!(
f,
"The specified env variable was found, but it did not valid: '{:?}'",
inner,
),
Parse(env_name) => {
Error::Parse(env_name) => {
write!(f, r#"Failed to parse environment variable "{}""#, env_name)
}
}

View File

@ -1,5 +1,5 @@
#[cfg(feature = "vec")]
pub mod vec;
mod vec;
#[cfg(feature = "vec")]
pub use vec::{CommaVec, SemiVec};

View File

@ -3,5 +3,8 @@ use estring::SepVec;
const COMMA: char = ',';
const SEMI: char = ';';
/// Splits substring by comma character and returns ``SepVec``
pub type CommaVec<T> = SepVec<T, COMMA>;
/// Splits substring by semicolon character and returns ``SepVec``
pub type SemiVec<T> = SepVec<T, SEMI>;

View File

@ -1,136 +1,43 @@
//! # enve
//!
//! Simple configuration with macro for rust application.
//! `enve` helps you work with environment variables and convert it to **any type**
//! using only **type annotations**.
//!
//! Look at the [examples](https://github.com/pleshevskiy/enve/tree/main/examples)
//! to see the power!
//!
//! ## Motivation
//! All standard environment variable types are included, but `enve` under the hood
//! uses [estring](https://github.com/pleshevskiy/estring), so you can easily create
//! your own type.
//!
//! I began to use rust with web programming experience where environment variables are widely used
//! and often there are more then 50 of them. First I looked at already created libraries.
//! But there it's necessary to initialise structure that needs to be moved to each function
//! where you need variable. It uses little bit memory, but configuration lifetime is as long
//! as application lifetime. Because of it I decided to create my own library.
//!
//!
//! ## Installation
//!
//! These macros require a Rust compiler version 1.31 or newer.
//!
//! Add `enve = { version = "1.0", features = ["macro"] }` as a dependency in `Cargo.toml`.
//!
//!
//! `Cargo.toml` example:
//!
//! ```toml
//! [package]
//! name = "my-crate"
//! version = "0.1.0"
//! authors = ["Me <user@rust-lang.org>"]
//!
//! [dependencies]
//! enve = { version = "1.0", features = ["macro"] }
//! ```
//!
//!
//! ## Basic usage
//! ## Getting started
//!
//! ```rust
//! use enve::config;
//! use std::env;
//! //use dotenv::dotenv;
//! use enve::SepVec;
//!
//! config! {
//! DEBUG: bool => false,
//! type MinusVec<T> = SepVec<T, '-'>;
//! type PlusVec<T> = SepVec<T, '+'>;
//! type MulVec<T> = SepVec<T, '*'>;
//!
//! #[env_name = "APP_HOST"]
//! HOST: String => "127.0.0.1",
//! fn main() -> Result<(), enve::Error> {
//! enve::sset("E", "10+5*2-3");
//!
//! database {
//! URL < (
//! "postgres://",
//! POSTGRES_USERNAME => "user",
//! ":",
//! POSTGRES_PASSWORD => "pass",
//! "@",
//! POSTGRES_HOST => "localhost:5432",
//! "/",
//! POSTGRES_DB => "test",
//! ),
//! let res: f32 = enve::get::<PlusVec<MinusVec<MulVec<f32>>>>("E")
//! .unwrap()
//! .iter()
//! .map(|p| {
//! p.iter()
//! .map(|m| m.iter().product::<f32>())
//! .reduce(|acc, v| acc - v)
//! .unwrap_or_default()
//! })
//! .sum::<f32>();
//!
//! pool {
//! MAX_SIZE: usize => 15,
//! },
//! },
//! println!("result: {}", res);
//!
//! sentry {
//! DSN: Option<&'static str>,
//! },
//!
//! feature {
//! static CORS: bool => false,
//!
//! static GRAPHQL_PLAYGROUND: bool => false,
//! },
//! }
//!
//! fn main () {
//! // dotenv().expect("dotenv setup to be successful");
//! // or
//! env::set_var("FEATURE_CORS", "true");
//!
//! config::init();
//! assert_eq!(config::HOST(), String::from("127.0.0.1"));
//! assert_eq!(config::database::URL(), String::from("postgres://user:pass@localhost:5432/test"));
//! assert_eq!(config::database::pool::MAX_SIZE(), 15);
//! assert_eq!(config::sentry::DSN(), None);
//! assert_eq!(config::feature::CORS(), true);
//! Ok(())
//! }
//! ```
//!
//! Macro is an optional feature, disabled by default. You can use this library without macro.
//!
//! ```rust
//! use enve::*;
//! use std::env;
//! // use dotenv::dotenv;
//!
//! fn main() {
//! // dotenv().expect("dotenv setup to be successful");
//! // or
//! env::set_var("DATABASE_URL", "postgres://127.0.0.1:5432/test");
//!
//! let database_url = get_env::<String>("DATABASE_URL").unwrap();
//! let new_profile: bool = get_env_or_default("FEATURE_NEW_PROFILE", false);
//! let articles_per_page: u32 = get_env_or_set_default("ARTICLES_PER_PAGE", 10);
//! }
//! ```
//!
//! ## Available features
//!
//! * **default** - ["primitives"]
//! * **macro** - Activates `config!` macros for easy configure web application.
//! * **primitives** - Group for features: `numbers` and `bool`.
//! * **numbers** - Group for features: `int`, `uint` and `float`.
//! * **int** - Group for features: `i8`, `i16`, `i32`, `i64`, `i128` and `isize`.
//! * **uint** - Group for features: `u8`, `u16`, `u32`, `u64`, `u128` and `usize`.
//! * **float** - Group for features: `f32` and `f64`
//! * **i8** - impl EnvString for `i8` type
//! * **i16** - impl EnvString for `i16` type
//! * **i32** - impl EnvString for `i32` type
//! * **i64** - impl EnvString for `i64` type
//! * **i128** - impl EnvString for `i128` type
//! * **isize** - impl EnvString for `isize` type
//! * **u8** - impl EnvString for `u8` type
//! * **u16** - impl EnvString for `u16` type
//! * **u32** - impl EnvString for `u32` type
//! * **u64** - impl EnvString for `u64` type
//! * **u128** - impl EnvString for `u128` type
//! * **usize** - impl EnvString for `usize` type
//! * **f32** - impl EnvString for `f32` type
//! * **f64** - impl EnvString for `f64` type
//! * **bool** - impl EnvString for `bool` type
//! * **json_array** - Add EnvString impl for vector type (uses optional `serde_json` package). ⚠ **_DEPRECATED_**
//!
// Rustc lints.
#![forbid(unsafe_code)]
@ -142,17 +49,16 @@
unused_imports,
unused_qualifications
)]
#![warn(missing_docs)]
// Clippy lints
#![deny(clippy::all)]
#![allow(clippy::needless_doctest_main)]
#![deny(clippy::pedantic)]
#![allow(clippy::module_name_repetitions)]
/////////////////////////////////////////////////////////////////////////////
mod core;
mod error;
pub mod estr;
mod estr;
pub use self::core::*;
pub use self::core::{get, get_or_set_default, sget, sset};
pub use self::error::Error;
pub use crate::core::{get, get_or_set_default, sget, sset};
pub use error::Error;
pub use estr::*;

View File

@ -1,613 +0,0 @@
mod test_case_1 {
itconfig::config! {
MISS_VARIABLE: bool,
}
#[test]
#[should_panic(expected = "Environment variable \"MISS_VARIABLE\" is missing")]
fn should_panic_if_miss_env_variable() {
config::init();
}
}
mod test_case_2 {
use std::env;
itconfig::config! {
DEBUG: bool,
}
#[test]
fn one_variable() {
env::set_var("DEBUG", "t");
config::init();
assert_eq!(config::DEBUG(), true);
env::remove_var("DEBUG");
}
}
mod test_case_3 {
itconfig::config! {
DEBUG: bool => true,
}
#[test]
fn one_variable_with_default_value() {
config::init();
assert_eq!(config::DEBUG(), true);
}
}
mod test_case_4 {
itconfig::config! {
FOO: bool => true,
BAR: bool => false,
}
#[test]
fn few_variables_with_default_value() {
config::init();
assert_eq!(config::FOO(), true);
assert_eq!(config::BAR(), false);
}
}
mod test_case_5 {
itconfig::config! {
NUMBER: i32 => 30,
BOOL: bool => true,
STR: String => "str",
STRING: String => "string".to_string(),
}
#[test]
fn different_types_with_default_value() {
config::init();
assert_eq!(config::NUMBER(), 30);
assert_eq!(config::BOOL(), true);
assert_eq!(config::STR(), "str".to_string());
assert_eq!(config::STRING(), "string".to_string());
}
}
mod test_case_6 {
use std::env;
itconfig::config! {
T_BOOL: bool,
TRUE_BOOL: bool,
NUM_BOOL: bool,
ON_BOOL: bool,
CAMEL_CASE: bool,
FALSE_BOOL: bool,
}
#[test]
fn convert_bool_type_value_from_env() {
env::set_var("T_BOOL", "t");
env::set_var("TRUE_BOOL", "true");
env::set_var("NUM_BOOL", "1");
env::set_var("ON_BOOL", "on");
env::set_var("CAMEL_CASE", "True");
env::set_var("FALSE_BOOL", "false");
config::init();
assert_eq!(config::T_BOOL(), true);
assert_eq!(config::TRUE_BOOL(), true);
assert_eq!(config::NUM_BOOL(), true);
assert_eq!(config::ON_BOOL(), true);
assert_eq!(config::CAMEL_CASE(), true);
assert_eq!(config::FALSE_BOOL(), false);
}
}
mod test_case_7 {
use std::env;
itconfig::config! {
I8: i8,
I16: i16,
I32: i32,
I64: i64,
I128: i128,
ISIZE: isize,
U8: u8,
U16: u16,
U32: u32,
U64: u64,
U128: u128,
USIZE: usize,
F32: f32,
F64: f64,
}
#[test]
fn convert_number_type_value_from_env() {
env::set_var("I8", "10");
env::set_var("I16", "10");
env::set_var("I32", "10");
env::set_var("I64", "10");
env::set_var("I128", "10");
env::set_var("ISIZE", "10");
env::set_var("U8", "10");
env::set_var("U16", "10");
env::set_var("U32", "10");
env::set_var("U64", "10");
env::set_var("U128", "10");
env::set_var("USIZE", "10");
env::set_var("F32", "10");
env::set_var("F64", "10");
config::init();
assert_eq!(config::I8(), 10);
assert_eq!(config::I16(), 10);
assert_eq!(config::I32(), 10);
assert_eq!(config::I64(), 10);
assert_eq!(config::ISIZE(), 10);
assert_eq!(config::U8(), 10);
assert_eq!(config::U16(), 10);
assert_eq!(config::U32(), 10);
assert_eq!(config::U64(), 10);
assert_eq!(config::USIZE(), 10);
assert_eq!(config::F32(), 10.0);
assert_eq!(config::F64(), 10.0);
}
}
mod test_case_8 {
itconfig::config! {
#![config(name = "custom_config_name")]
DEBUG: bool => true,
}
#[test]
fn change_configuration_module_name() {
custom_config_name::init();
assert_eq!(custom_config_name::DEBUG(), true);
}
}
mod test_case_9 {
use std::env;
itconfig::config! {
DEBUG: bool => true,
DB {
HOST: bool,
PORT: bool => true,
USERNAME: bool => true,
}
APP {}
}
#[test]
fn configuration_with_namespace() {
env::set_var("DB_HOST", "t");
config::init();
assert_eq!(config::DEBUG(), true);
assert_eq!(config::DB::HOST(), true);
}
}
mod test_case_10 {
itconfig::config! {
FIRST {
SECOND {
THIRD {
FOO: u32 => 50,
}
}
}
}
#[test]
fn configuration_with_nested_namespaces() {
config::init();
assert_eq!(config::FIRST::SECOND::THIRD::FOO(), 50);
}
}
mod test_case_11 {
itconfig::config! {
FIRST {
#[cfg(feature = "meta_namespace")]
SECOND {
THIRD {
FOO: u32 => 50,
}
}
}
}
#[cfg(feature = "meta_namespace")]
#[test]
fn configuration_namespaces_with_custom_meta() {
config::init();
assert_eq!(config::FIRST::SECOND::THIRD::FOO(), 50);
}
}
mod test_case_12 {
use std::env;
itconfig::config! {
testing: bool,
namespace {
foo: bool,
}
}
#[test]
fn configuration_variables_and_namespace_in_lowercase() {
env::set_var("TESTING", "t");
env::set_var("NAMESPACE_FOO", "t");
config::init();
assert_eq!(config::testing(), true);
assert_eq!(config::namespace::foo(), true);
}
}
mod test_case_13 {
use std::env;
itconfig::config! {
#[env_name = "MY_CUSTOM_NAME"]
PER_PAGE: i32,
APP {
#[env_name = "MY_CUSTOM_NAME"]
RECIPES_PER_PAGE: i32,
}
}
#[test]
fn custom_environment_name_for_variable() {
env::set_var("MY_CUSTOM_NAME", "95");
config::init();
assert_eq!(config::PER_PAGE(), 95);
assert_eq!(config::APP::RECIPES_PER_PAGE(), 95);
}
}
mod test_case_14 {
use std::env;
itconfig::config! {
#[cfg(feature = "postgres")]
#[env_name = "MY_CUSTOM_NAME"]
DATABASE_URL: String,
#[cfg(not(feature = "postgres"))]
#[env_name = "MY_CUSTOM_NAME"]
DATABASE_URL: i32,
}
#[test]
fn stranger_meta_data() {
env::set_var("MY_CUSTOM_NAME", "95");
config::init();
#[cfg(not(feature = "postgres"))]
assert_eq!(config::DATABASE_URL(), 95);
#[cfg(feature = "postgres")]
assert_eq!(config::DATABASE_URL(), "95");
}
}
mod test_case_15 {
use std::env;
itconfig::config! {
DEFAULT_ENV_STRING: String => "localhost",
DEFAULT_ENV_BOOLEAN: bool => true,
DEFAULT_ENV_UINT: u32 => 40,
DEFAULT_ENV_FLOAT: f64 => 40.9,
}
#[test]
fn setting_default_env_variable() {
config::init();
assert_eq!(env::var("DEFAULT_ENV_STRING"), Ok("localhost".to_string()));
assert_eq!(env::var("DEFAULT_ENV_BOOLEAN"), Ok("true".to_string()));
assert_eq!(env::var("DEFAULT_ENV_UINT"), Ok("40".to_string()));
assert_eq!(env::var("DEFAULT_ENV_FLOAT"), Ok("40.9".to_string()));
}
}
mod test_case_16 {
use std::env;
itconfig::config! {
DATABASE_URL < (
"postgres://",
POSTGRES_USERNAME,
":",
POSTGRES_PASSWORD,
"@",
POSTGRES_HOST,
"/",
POSTGRES_DB,
),
}
#[test]
fn concatenate_environment_variables() {
env::set_var("POSTGRES_USERNAME", "user");
env::set_var("POSTGRES_PASSWORD", "pass");
env::set_var("POSTGRES_HOST", "localhost");
env::set_var("POSTGRES_DB", "test");
config::init();
assert_eq!(
config::DATABASE_URL(),
String::from("postgres://user:pass@localhost/test")
);
}
}
mod test_case_17 {
use std::env;
itconfig::config! {
DEFAULT_CONCAT_ENV < (
"string",
"/",
SETTING_DEFAULT_CONCAT_ENV_VARIABLE,
),
}
#[test]
fn setting_default_concat_env_variable() {
env::set_var("SETTING_DEFAULT_CONCAT_ENV_VARIABLE", "custom");
config::init();
assert_eq!(
env::var("DEFAULT_CONCAT_ENV"),
Ok("string/custom".to_string())
);
}
}
mod test_case_18 {
itconfig::config! {
DATABASE_URL < (
"postgres://",
PG_USERNAME,
":",
PG_PASSWORD,
"@",
PG_HOST,
"/",
PG_DB,
),
}
#[test]
#[should_panic(expected = "Environment variable \"PG_USERNAME\" is missing")]
fn concatenate_not_defined_environment_variables() {
config::init();
}
}
mod test_case_19 {
use std::env;
itconfig::config! {
CONCATENATED_DATABASE_URL < (
"postgres://",
NOT_DEFINED_PG_USERNAME => "user",
":",
NOT_DEFINED_PG_PASSWORD => "pass",
"@",
NOT_DEFINED_PG_HOST => "localhost:5432",
"/",
NOT_DEFINED_PG_DB => "test",
),
}
#[test]
fn default_value_for_concatenate_env_parameter() {
config::init();
assert_eq!(
env::var("CONCATENATED_DATABASE_URL"),
Ok("postgres://user:pass@localhost:5432/test".to_string())
);
}
}
mod test_case_20 {
use std::env;
use std::env::VarError;
itconfig::config! {
#[env_name = "CUSTOM_CONCAT_ENVNAME"]
CONCAT_ENVVAR < (
"postgres://",
NOT_DEFINED_PG_USERNAME => "user",
":",
NOT_DEFINED_PG_PASSWORD => "pass",
"@",
NOT_DEFINED_PG_HOST => "localhost:5432",
"/",
NOT_DEFINED_PG_DB => "test",
),
}
#[test]
fn envname_meta_for_concatenated_env_variable() {
config::init();
assert_eq!(
env::var("CUSTOM_CONCAT_ENVNAME"),
Ok("postgres://user:pass@localhost:5432/test".to_string())
);
assert_eq!(env::var("CONCAT_ENVVAR"), Err(VarError::NotPresent));
}
}
mod test_case_21 {
use std::env;
use std::env::VarError;
itconfig::config! {
CONCATED_NAMESPACE {
CONCAT_ENVVAR < (
"postgres://",
NOT_DEFINED_PG_USERNAME => "user",
":",
NOT_DEFINED_PG_PASSWORD => "pass",
"@",
NOT_DEFINED_PG_HOST => "localhost:5432",
"/",
NOT_DEFINED_PG_DB => "test",
),
}
}
#[test]
fn concatenated_environment_variable_in_namespace() {
config::init();
assert_eq!(
env::var("CONCATED_NAMESPACE_CONCAT_ENVVAR"),
Ok("postgres://user:pass@localhost:5432/test".to_string())
);
assert_eq!(env::var("CONCAT_ENVVAR"), Err(VarError::NotPresent));
}
}
mod test_case_22 {
itconfig::config! {
static STATIC_STR => "test",
static STATIC_STRING: String => "test",
static STATIC_I8: i8 => 1,
static STATIC_I16: i16 => 1,
static STATIC_I32: i32 => 1,
static STATIC_I64: i64 => 1,
static STATIC_I128: i128 => 1,
static STATIC_ISIZE: isize => 1,
static STATIC_U8: u8 => 1,
static STATIC_U16: u16 => 1,
static STATIC_U32: u32 => 1,
static STATIC_U64: u64 => 1,
static STATIC_U128: u128 => 1,
static STATIC_USIZE: usize => 1,
static STATIC_F32: f32 => 1,
static STATIC_F64: f64 => 1,
static STATIC_CONCAT_VARIABLE < (
"static ",
STATIC_CONCAT_PART => "part",
),
static STATIC_VEC: Vec<u32> => vec![1],
}
#[test]
fn static_variables() {
config::init();
assert_eq!(config::STATIC_STR(), "test");
assert_eq!(config::STATIC_STRING(), "test".to_string());
assert_eq!(config::STATIC_I8(), 1);
assert_eq!(config::STATIC_I16(), 1);
assert_eq!(config::STATIC_I32(), 1);
assert_eq!(config::STATIC_I64(), 1);
assert_eq!(config::STATIC_I128(), 1);
assert_eq!(config::STATIC_ISIZE(), 1);
assert_eq!(config::STATIC_U8(), 1);
assert_eq!(config::STATIC_U16(), 1);
assert_eq!(config::STATIC_U32(), 1);
assert_eq!(config::STATIC_U64(), 1);
assert_eq!(config::STATIC_U128(), 1);
assert_eq!(config::STATIC_USIZE(), 1);
assert_eq!(config::STATIC_F32(), 1.0);
assert_eq!(config::STATIC_F64(), 1.0);
assert_eq!(config::STATIC_CONCAT_VARIABLE(), "static part".to_string());
assert_eq!(config::STATIC_VEC(), vec![1]);
}
}
mod test_case_23 {
use std::env;
itconfig::config! {
SOMETHING: Option<&'static str>,
#[env_name = "SOMETHING"]
STD_SOMETHING: std::option::Option<&'static str>,
#[env_name = "SOMETHING"]
CORE_SOMETHING: core::option::Option<&'static str>,
NOTHING: Option<&'static str>,
}
#[test]
fn optional_variables() {
env::set_var("SOMETHING", "hello world");
assert_eq!(config::SOMETHING(), Some("hello world"));
assert_eq!(config::STD_SOMETHING(), Some("hello world"));
assert_eq!(config::CORE_SOMETHING(), Some("hello world"));
assert_eq!(config::NOTHING(), None);
}
}
mod test_case_24 {
use std::env;
itconfig::config! {
MY_VEC: Vec<&'static str>,
#[env_name = "MY_VEC"]
STD_VEC: std::vec::Vec<&'static str>,
}
#[test]
fn vector_of_values() {
env::set_var("MY_VEC", "paypal,stripe");
assert_eq!(config::MY_VEC(), vec!["paypal", "stripe"]);
assert_eq!(config::STD_VEC(), vec!["paypal", "stripe"]);
}
}
mod test_case_25 {
use std::env;
itconfig::config! {
#[sep = ";"]
CUSTOM_SEP_MY_VEC: Vec<&'static str>,
#[env_name = "CUSTOM_SEP_MY_VEC"]
#[sep = ";"]
CUSTOM_SEP_STD_VEC: std::vec::Vec<&'static str>,
}
#[test]
fn custom_separator_for_vector() {
env::set_var("CUSTOM_SEP_MY_VEC", "paypal;stripe");
assert_eq!(config::CUSTOM_SEP_MY_VEC(), vec!["paypal", "stripe"]);
assert_eq!(config::CUSTOM_SEP_STD_VEC(), vec!["paypal", "stripe"]);
}
}
mod test_case_26 {
use std::env;
itconfig::config! {
OPTION_VEC: Option<Vec<&'static str>>,
}
#[test]
fn optional_vec() {
env::set_var("OPTION_VEC", "paypal,stripe");
assert_eq!(config::OPTION_VEC(), Some(vec!["paypal", "stripe"]));
}
}