diff --git a/Cargo.lock b/Cargo.lock index 664d82e..abb2a7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -175,6 +175,26 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" +[[package]] +name = "enve" +version = "1.1.1" +dependencies = [ + "criterion", + "enve_mod", + "lazy_static", +] + +[[package]] +name = "enve_mod" +version = "1.1.1" +dependencies = [ + "enve", + "lazy_static", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "half" version = "1.8.2" @@ -190,26 +210,6 @@ dependencies = [ "libc", ] -[[package]] -name = "itconfig" -version = "1.1.1" -dependencies = [ - "criterion", - "itconfig-macro", - "lazy_static", -] - -[[package]] -name = "itconfig-macro" -version = "1.1.1" -dependencies = [ - "itconfig", - "lazy_static", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "itertools" version = "0.10.3" diff --git a/Cargo.toml b/Cargo.toml index 42e7df4..e7ac56f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [workspace] members = [ - "itconfig-macro", + "enve_mod", ] [package] -name = "itconfig" +name = "enve" version = "1.1.1" authors = ["Dmitriy Pleshevskiy "] description = "Easy build a configs from environment variables and use it in globally." @@ -12,9 +12,9 @@ categories = ["config", "web-programming"] keywords = ["config", "env", "configuration", "environment", "macro"] edition = "2018" license = "MIT" -repository = "https://github.com/pleshevskiy/itconfig-rs" -homepage = "https://github.com/pleshevskiy/itconfig-rs" -documentation = "https://docs.rs/itconfig" +repository = "https://github.com/pleshevskiy/enve" +homepage = "https://github.com/pleshevskiy/enve" +documentation = "https://docs.rs/enve" readme = "../README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -22,14 +22,14 @@ readme = "../README.md" [features] default = [] -macro = ["itconfig-macro"] +macro = ["enve_mod"] number = [] bool = [] vec = [] [dependencies] -itconfig-macro = { version = "1.1", path = "itconfig-macro", optional = true } +enve_mod = { version = "1.1", path = "./enve_mod", optional = true } [dev-dependencies] lazy_static = "1.4.0" diff --git a/LICENSE b/LICENSE index ae03a7f..96a1a25 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 IceTemple +Copyright (c) 2019 pleshevskiy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index ca2f8aa..1bb5dec 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# itconfig +# enve -[![CI](https://github.com/icetemple/itconfig-rs/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/icetemple/itconfig-rs/actions/workflows/ci.yml) +[![CI](https://github.com/pleshevskiy/enve/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/pleshevskiy/enve/actions/workflows/ci.yml) [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) -[![Documentation](https://docs.rs/itconfig/badge.svg)](https://docs.rs/itconfig) -[![Crates.io](https://img.shields.io/crates/v/itconfig)](https://crates.io/crates/itconfig) -![Crates.io](https://img.shields.io/crates/l/itconfig) +[![Documentation](https://docs.rs/pleshevskiy/badge.svg)](https://docs.rs/enve) +[![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. @@ -23,7 +23,7 @@ of it I decided to create my own library. The MSRV is 1.39.0 -Add `itconfig = { version = "1.0", features = ["macro"] }` as a dependency in +Add `enve = { version = "1.0", features = ["mod"] }` as a dependency in `Cargo.toml`. `Cargo.toml` example: @@ -35,17 +35,16 @@ version = "0.1.0" authors = ["Me "] [dependencies] -itconfig = { version = "1.0", features = ["macro"] } +enve = { version = "1.0", features = ["mod"] } ``` ## Basic usage ```rust -use itconfig::config; use std::env; //use dotenv::dotenv; -config! { +enve::mod! { DEBUG: bool => false, #[env_name = "APP_HOST"] @@ -97,7 +96,6 @@ Macro is an optional feature, disabled by default. You can use this library without macro ```rust -use itconfig::*; use std::env; // use dotenv::dotenv; @@ -106,9 +104,9 @@ fn main() { // 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); + 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); } ``` @@ -120,39 +118,19 @@ cargo test --all-features ## 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_** +- **number** - Group for features: `int`, `uint` and `float`. +- **bool** - impl EnvString for `bool` type `serde_json` package). ⚠ + **_DEPRECATED_** ## License -[MIT] © [Ice Temple](https://github.com/icetemple) +[MIT] © [pleshevskiy](https://github.com/pleshevskiy) ## Contributors [pleshevskiy](https://github.com/pleshevskiy) (Dmitriy Pleshevskiy) – creator, maintainer. -[documentation]: https://docs.rs/itconfig -[MIT]: https://github.com/icetemple/itconfig-rs/blob/master/LICENSE +[documentation]: https://docs.rs/enve +[MIT]: https://github.com/icetemple/enve-rs/blob/master/LICENSE diff --git a/benches/main_benches.rs b/benches/main_benches.rs index bce427e..3142d78 100644 --- a/benches/main_benches.rs +++ b/benches/main_benches.rs @@ -4,14 +4,14 @@ use std::env; #[macro_use] extern crate lazy_static; #[macro_use] -extern crate itconfig; +extern crate enve; fn setup_env_var(key: &'static str, initial: String) { env::set_var(key, initial); } fn source_get_env() -> u32 { - itconfig::get_env::("TEST").unwrap() + enve::get::("TEST").unwrap() } fn lazy_get_env() -> u32 { diff --git a/itconfig-macro/Cargo.toml b/enve_mod/Cargo.toml similarity index 75% rename from itconfig-macro/Cargo.toml rename to enve_mod/Cargo.toml index 4d88505..bb3b161 100644 --- a/itconfig-macro/Cargo.toml +++ b/enve_mod/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "itconfig-macro" +name = "enve_mod" version = "1.1.1" authors = ["Dmitriy Pleshevskiy "] description = "Easy build a configs from environment variables and use it in globally." @@ -7,9 +7,9 @@ categories = ["config", "web-programming"] keywords = ["config", "env", "configuration", "environment", "macro"] edition = "2018" license = "MIT" -repository = "https://github.com/pleshevskiy/itconfig-rs" -homepage = "https://github.com/pleshevskiy/itconfig-rs" -documentation = "https://docs.rs/itconfig" +repository = "https://github.com/pleshevskiy/enve" +homepage = "https://github.com/pleshevskiy/enve" +documentation = "https://docs.rs/enve" readme = "../README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -22,7 +22,7 @@ quote = "1.0.9" proc-macro2 = "1.0.24" [dev-dependencies] -itconfig = { path = ".." } +enve = { path = ".." } lazy_static = "1.4.0" [badges] diff --git a/itconfig-macro/src/ast.rs b/enve_mod/src/ast.rs similarity index 100% rename from itconfig-macro/src/ast.rs rename to enve_mod/src/ast.rs diff --git a/itconfig-macro/src/expand.rs b/enve_mod/src/expand.rs similarity index 100% rename from itconfig-macro/src/expand.rs rename to enve_mod/src/expand.rs diff --git a/itconfig-macro/src/lib.rs b/enve_mod/src/lib.rs similarity index 100% rename from itconfig-macro/src/lib.rs rename to enve_mod/src/lib.rs diff --git a/itconfig-macro/src/parse.rs b/enve_mod/src/parse.rs similarity index 100% rename from itconfig-macro/src/parse.rs rename to enve_mod/src/parse.rs diff --git a/itconfig-macro/src/utils.rs b/enve_mod/src/utils.rs similarity index 100% rename from itconfig-macro/src/utils.rs rename to enve_mod/src/utils.rs diff --git a/src/core.rs b/src/core.rs index c31af94..95a9f85 100644 --- a/src/core.rs +++ b/src/core.rs @@ -8,6 +8,7 @@ pub mod vec; #[cfg(feature = "vec")] pub use vec::*; +use crate::error::Error; use std::convert::{Infallible, TryFrom}; /// Wrapper under String type. @@ -18,6 +19,14 @@ use std::convert::{Infallible, TryFrom}; #[derive(Debug, Default, PartialEq, Eq, Clone)] pub struct EString(String); +impl EString { + #[inline] + pub fn parse>(self) -> Result { + let orig = self.0.clone(); + >::try_from(self).map_err(|_| Error::Parse(orig)) + } +} + impl From for EString where T: std::fmt::Display, diff --git a/src/lib.rs b/src/lib.rs index 4182a44..d442af4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! # itconfig +//! # enve //! //! Simple configuration with macro for rust application. //! @@ -16,7 +16,7 @@ //! //! These macros require a Rust compiler version 1.31 or newer. //! -//! Add `itconfig = { version = "1.0", features = ["macro"] }` as a dependency in `Cargo.toml`. +//! Add `enve = { version = "1.0", features = ["macro"] }` as a dependency in `Cargo.toml`. //! //! //! `Cargo.toml` example: @@ -28,14 +28,14 @@ //! authors = ["Me "] //! //! [dependencies] -//! itconfig = { version = "1.0", features = ["macro"] } +//! enve = { version = "1.0", features = ["macro"] } //! ``` //! //! //! ## Basic usage //! //! ```rust -//! use itconfig::config; +//! use enve::config; //! use std::env; //! //use dotenv::dotenv; //! @@ -90,7 +90,7 @@ //! Macro is an optional feature, disabled by default. You can use this library without macro. //! //! ```rust -//! use itconfig::*; +//! use enve::*; //! use std::env; //! // use dotenv::dotenv; //! @@ -157,6 +157,6 @@ pub use self::error::*; pub use self::utils::*; #[cfg(feature = "macro")] -extern crate itconfig_macro; +extern crate enve_mod; #[cfg(feature = "macro")] -pub use itconfig_macro::*; +pub use enve_mod::*; diff --git a/src/utils.rs b/src/utils.rs index fa1ed61..1f06865 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,36 +1,35 @@ use crate::core::EString; use crate::error::Error; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryFrom; use std::env; -pub fn get_env_or_set_default(env_name: &str, default: R) -> Result +pub fn get_or_set_default(env_name: &str, default: R) -> Result where R: TryFrom + std::fmt::Display, { - get_env::(env_name).or_else(|err| match err { - Error::NotPresent => { - let val = default.to_string(); - env::set_var(env_name, &val); - EString::from(val) - .try_into() - .map_err(|_| Error::Parse(default.to_string())) - } + get::(env_name).or_else(|err| match err { + Error::NotPresent => set(env_name, &default).parse(), _ => Err(err), }) } -pub fn get_env(env_name: &str) -> Result +pub fn get(env_name: &str) -> Result where R: TryFrom, { env::var(env_name) .map_err(From::from) .map(EString::from) - .and_then(|val| { - val.clone() - .try_into() - .map_err(|_| Error::Parse(val.to_string())) - }) + .and_then(EString::parse) +} + +pub fn set(env_name: &str, value: V) -> EString +where + V: std::fmt::Display, +{ + let val = value.to_string(); + env::set_var(env_name, &val); + val.into() } #[cfg(test)] @@ -41,7 +40,17 @@ mod tests { impl std::fmt::Display for TestCase { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "get_env_{}", N) + write!(f, "test_case_{}", N) + } + } + + #[test] + fn should_add_env_variable_to_process() { + let en = TestCase::<0>.to_string(); + set(&en, "hello"); + match env::var(&en) { + Ok(var) => assert_eq!(&var, "hello"), + _ => unreachable!(), } } @@ -49,7 +58,7 @@ mod tests { fn should_return_variable() { let en = TestCase::<1>.to_string(); env::set_var(&en, "hello"); - match get_env::<&str>(&en) { + match get::<&str>(&en) { Ok(res) => assert_eq!(res, "hello"), _ => unreachable!(), }; @@ -58,7 +67,7 @@ mod tests { #[test] fn should_throw_no_present_error() { let en = TestCase::<2>.to_string(); - match get_env::<&str>(&en) { + match get::<&str>(&en) { Err(Error::NotPresent) => {} _ => unreachable!(), }; @@ -68,7 +77,7 @@ mod tests { fn should_set_default_if_var_is_no_present() { let en = TestCase::<3>.to_string(); let orig = "hello"; - match get_env_or_set_default(&en, orig) { + match get_or_set_default(&en, orig) { Ok(res) => { assert_eq!(res, orig); assert_eq!(env::var(&en).unwrap(), orig); @@ -85,7 +94,7 @@ mod tests { fn should_throw_parse_error() { let en = TestCase::<4>.to_string(); env::set_var(&en, "-10"); - match get_env::(&en) { + match get::(&en) { Err(Error::Parse(orig)) => { assert_eq!(orig, String::from("-10")) } @@ -97,7 +106,7 @@ mod tests { fn should_set_default_num_if_var_is_no_present() { let en = TestCase::<5>.to_string(); let orig = 10; - match get_env_or_set_default(&en, orig) { + match get_or_set_default(&en, orig) { Ok(res) => { assert_eq!(res, orig); assert_eq!(env::var(&en).unwrap(), "10"); @@ -130,7 +139,7 @@ mod tests { en.push_str(val.as_ref()); env::set_var(&en, val); - match get_env::(&en) { + match get::(&en) { Ok(res) => assert_eq!(res, *expected), _ => unreachable!(), }; @@ -148,7 +157,7 @@ mod tests { let en = TestCase::<6>.to_string(); env::set_var(&en, "1,2,3,4,5"); - match get_env::>(&en) { + match get::>(&en) { Ok(res) => assert_eq!(*res, vec![1, 2, 3, 4, 5]), _ => unreachable!(), }; @@ -158,7 +167,7 @@ mod tests { fn should_throw_parse_vec_error() { let en = TestCase::<7>.to_string(); env::set_var(&en, "1,2,3,4,5"); - match get_env::>(&en) { + match get::>(&en) { Err(Error::Parse(orig)) => { assert_eq!(orig, String::from("1,2,3,4,5")) } @@ -170,7 +179,7 @@ mod tests { fn should_set_default_vector_if_var_is_no_present() { let en = TestCase::<8>.to_string(); let orig = CommaVec::from(vec![1, 2, 3, 4]); - match get_env_or_set_default(&en, orig.clone()) { + match get_or_set_default(&en, orig.clone()) { Ok(res) => { assert_eq!(res, orig); assert_eq!(env::var(&en).unwrap(), "1,2,3,4");