Skip to content

Commit

Permalink
add support of clap derive feature #15
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Coenen <[email protected]>
  • Loading branch information
bnjjj committed Apr 17, 2022
1 parent 31135ad commit 4bee406
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 13 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
[workspace]
members = ["twelf", "config-derive"]

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct Conf {
// Will generate global arguments for each of your fields inside your configuration struct
let app = clap::Command::new("test").args(&Conf::clap_args());
// If you're looking for how to use with clap derive feature, check in the examples directory (twelf/examples/clap_derive.rs)
// Init configuration with layers, each layers override only existing fields
let config = Conf::with_layers(&[
Expand All @@ -67,7 +68,7 @@ Check [here](./twelf/examples) for more examples.
Twelf supports crate features, if you only want support for `json`, `env` and `toml` then you just have to add this to your `Cargo.toml`

```toml
twelf = { version = "0.3", default-features = false, features = ["json", "toml", "env"] }
twelf = { version = "0.4", default-features = false, features = ["json", "toml", "env"] }
```

Default features are `["env", "dhall", "clap", "ini", "json", "yaml", "toml"]`
Expand Down
2 changes: 1 addition & 1 deletion config-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
name = "config-derive"
readme = "README.md"
repository = "https://github.com/bnjjj/twelf"
version = "0.3.1"
version = "0.4.0"


# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
13 changes: 7 additions & 6 deletions config-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub fn config(_attrs: TokenStream, item: TokenStream) -> TokenStream {
use std::iter::FromIterator;
let mut res: std::collections::HashMap<String, ::twelf::reexports::serde_json::Value> = std::collections::HashMap::new();
for layer in layers {
let extension = Self::parse(layer)?;
let extension = Self::parse_twelf(layer)?;
res.extend(
extension
.as_object()
Expand All @@ -146,11 +146,11 @@ pub fn config(_attrs: TokenStream, item: TokenStream) -> TokenStream {
::twelf::reexports::log::debug!(target: "twelf", "{}={}", key, val);
}

::twelf::reexports::serde_json::from_value(::twelf::reexports::serde_json::Value::Object(::twelf::reexports::serde_json::Map::from_iter(res.into_iter()))).map_err(|e| ::twelf::Error::Deserialize(e.to_string()))
::twelf::reexports::serde_json::from_value(::twelf::reexports::serde_json::Value::Object(::twelf::reexports::serde_json::Map::from_iter(res.into_iter()))).map_err(|e| ::twelf::Error::Deserialize(format!("config error: {}", e.to_string())))
}
#clap_method

fn parse(priority: &::twelf::Layer) -> Result<::twelf::reexports::serde_json::Value, ::twelf::Error>
fn parse_twelf(priority: &::twelf::Layer) -> Result<::twelf::reexports::serde_json::Value, ::twelf::Error>
{
#[derive(::twelf::reexports::serde::Deserialize, ::twelf::reexports::serde::Serialize)]
#[serde(crate = "::twelf::reexports::serde")]
Expand Down Expand Up @@ -187,15 +187,16 @@ fn build_clap_branch(
.iter()
.map(|field_name| field_name.to_kebab_case());

let field_names_clap_cloned = field_names_clap.clone();
#[cfg(feature = "clap")]
let clap_branch = quote! { ::twelf::Layer::Clap(matches) => {
let mut map: std::collections::HashMap<String, String> = std::collections::HashMap::new();

#(
if let Some(vmatch) = matches.value_of(#fields_name) {
if let Some(vmatch) = matches.value_of(#field_names_clap_cloned) {
map.insert(String::from(#fields_name), vmatch.to_string());
} else if #fields_is_boolean {
if matches.is_present(#fields_name) {
if matches.is_present(#field_names_clap_cloned) {
map.insert(String::from(#fields_name), String::from("true"));
}
}
Expand All @@ -209,7 +210,7 @@ fn build_clap_branch(
#[cfg(feature = "clap")]
let clap_method = quote! { pub fn clap_args() -> Vec<::twelf::reexports::clap::Arg<'static>> {
vec![#(
::twelf::reexports::clap::Arg::new(#fields_name).long(#field_names_clap).help(#docs).takes_value(!#fields_is_boolean).global(true)
::twelf::reexports::clap::Arg::new(#field_names_clap).long(#field_names_clap).help(#docs).takes_value(!#fields_is_boolean).global(true)
),*]
}};
#[cfg(not(feature = "clap"))]
Expand Down
6 changes: 3 additions & 3 deletions twelf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
name = "twelf"
readme = "../README.md"
repository = "https://github.com/bnjjj/twelf"
version = "0.3.1"
version = "0.4.0"

[dependencies]
clap_rs = { version = "3.0", package = "clap", optional = true }
config-derive = { path = "../config-derive", version = "0.3" }
clap_rs = { version = "3.0", package = "clap", optional = true, features = ["derive"] }
config-derive = { path = "../config-derive", version = "0.4" }
envy = { version = "0.4.1", git = "https://github.com/bnjjj/envy", branch = "master", optional = true }
log = "0.4.14"
serde = { version = "1", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion twelf/examples/clap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ fn main() {
.unwrap();

println!("config - {:?}", config);
}
}
40 changes: 40 additions & 0 deletions twelf/examples/clap_derive.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![allow(dead_code)]

use clap_rs as clap;
use clap::{Parser, Subcommand, CommandFactory};
use twelf::{config, Layer};

#[config]
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Config {
#[clap(
long,
help = "Documentation inside clap, to specifiy db_host",
)]
db_host: String,
#[clap(
long,
short,
help = "The number of threads",
)]
#[clap(required = false)]
threads: usize,
#[clap(
long,
short,
help = "Put in verbose mode",
)]
verbose: bool,
}

// execute `cargo run --example clap_derive -- --help` to display help and documentation
// execute `cargo run --example clap_derive -- --db-host localhost --threads 5` to set configuration
fn main() {
let matches = Config::command().ignore_errors(true).get_matches();
let config =
Config::with_layers(&[Layer::Env(Some(String::from("APP_"))), Layer::Clap(matches)])
.unwrap();

println!("config - {:?}", config);
}

0 comments on commit 4bee406

Please sign in to comment.