diff --git a/Cargo.lock b/Cargo.lock index 4c96d5c..b5ace65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index c2f27ee..0a42263 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,20 @@ -[workspace] -members = [] - [package] name = "enve" -version = "1.1.1" +version = "0.1.0" authors = ["Dmitriy Pleshevskiy "] -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"] diff --git a/README.md b/README.md index 1bb5dec..595fea7 100644 --- a/README.md +++ b/README.md @@ -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 = SepVec; +type PlusVec = SepVec; +type MulVec = SepVec; + +fn main() -> Result<(), enve::Error> { + enve::sset("E", "10+5*2-3"); + + let res: f32 = enve::get::>>>("E") + .unwrap() + .iter() + .map(|p| { + p.iter() + .map(|m| m.iter().product::()) + .reduce(|acc, v| acc - v) + .unwrap_or_default() + }) + .sum::(); + + 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 "] [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::("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 diff --git a/examples/README.md b/examples/README.md index d917ddd..e8dfe34 100644 --- a/examples/README.md +++ b/examples/README.md @@ -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`. diff --git a/examples/calc.rs b/examples/calc.rs index 129b488..94e3801 100644 --- a/examples/calc.rs +++ b/examples/calc.rs @@ -1,4 +1,4 @@ -use enve::estr::SepVec; +use enve::SepVec; type MinusVec = SepVec; type PlusVec = SepVec; diff --git a/src/core.rs b/src/core.rs index 61712a4..74cb8df 100644 --- a/src/core.rs +++ b/src/core.rs @@ -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::(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(env_name: &str, default: R) -> Result where R: TryFrom + std::fmt::Display, @@ -12,25 +36,84 @@ where }) } -pub fn get(env_name: &str) -> Result +/// 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::(key) { +/// Ok(res) => assert_eq!(res, 10), +/// Err(e) => println!("couldn't interpret {key}: {e}"), +/// } +/// ``` +pub fn get(key: &str) -> Result where R: TryFrom, { - 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 { - 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 { + std::env::var(key).map_err(Error::from).map(EString::from) } -pub fn sset(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(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::(&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::(&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::>(&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!(), }; diff --git a/src/error.rs b/src/error.rs index a6ce455..ea716f6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -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) } } diff --git a/src/estr.rs b/src/estr.rs index e0fe52c..4e4be5c 100644 --- a/src/estr.rs +++ b/src/estr.rs @@ -1,5 +1,5 @@ #[cfg(feature = "vec")] -pub mod vec; +mod vec; #[cfg(feature = "vec")] pub use vec::{CommaVec, SemiVec}; diff --git a/src/estr/vec.rs b/src/estr/vec.rs index 4307856..245b0e5 100644 --- a/src/estr/vec.rs +++ b/src/estr/vec.rs @@ -3,5 +3,8 @@ use estring::SepVec; const COMMA: char = ','; const SEMI: char = ';'; +/// Splits substring by comma character and returns ``SepVec`` pub type CommaVec = SepVec; + +/// Splits substring by semicolon character and returns ``SepVec`` pub type SemiVec = SepVec; diff --git a/src/lib.rs b/src/lib.rs index e82bb54..c0c3d76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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 "] -//! -//! [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 = SepVec; +//! type PlusVec = SepVec; +//! type MulVec = SepVec; //! -//! #[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::>>>("E") +//! .unwrap() +//! .iter() +//! .map(|p| { +//! p.iter() +//! .map(|m| m.iter().product::()) +//! .reduce(|acc, v| acc - v) +//! .unwrap_or_default() +//! }) +//! .sum::(); //! -//! 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::("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::*; diff --git a/tests/config_macro.rs b/tests/config_macro.rs deleted file mode 100644 index e521d85..0000000 --- a/tests/config_macro.rs +++ /dev/null @@ -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 => 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>, - } - - #[test] - fn optional_vec() { - env::set_var("OPTION_VEC", "paypal,stripe"); - - assert_eq!(config::OPTION_VEC(), Some(vec!["paypal", "stripe"])); - } -}