Skip to content

Commit

Permalink
Public api cleanup
Browse files Browse the repository at this point in the history
Signed-off-by: David McNeil <[email protected]>
  • Loading branch information
davidMcneil committed Apr 21, 2020
1 parent b1c226f commit 0a6916d
Show file tree
Hide file tree
Showing 10 changed files with 308 additions and 167 deletions.
7 changes: 0 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
# ConfigOpt

## TODO
- Modify configopt_type_derive's `TryFrom` if type does not implement `Debug`
- How to set booleans
- How to handle excludes in clap
- How to handle subcommands
- How to handle flattened structures
2 changes: 0 additions & 2 deletions configopt-derive/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# ConfigOpt Derive

TODO
108 changes: 58 additions & 50 deletions configopt-derive/src/configopt_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl ConfigOptConstruct {
Self::Struct(_, parsed_fields) => {
let configopt_take = generate::core::take(&parsed_fields, &other);
let configopt_patch = generate::core::patch(&parsed_fields, &other);
// let configopt_merge = merge(&parsed_fields);
let configopt_take_for = generate::core::take_for(&parsed_fields, &other);
// let configopt_clear = clear(&parsed_fields);
// let configopt_is_empty = is_empty(&parsed_fields);
// let configopt_is_complete = is_complete(&parsed_fields);
Expand Down Expand Up @@ -158,10 +158,10 @@ impl ConfigOptConstruct {
#configopt_patch
}

// /// Take each field from `self` and set it in `other`
// pub fn merge(&mut self, other: &mut #ident) {
// #configopt_merge
// }
/// Take each field from `self` and set it in `other`
pub fn take_for(&mut self, other: &mut #ident) {
#configopt_take_for
}

// /// Clear all fields from `self`
// pub fn clear(&mut self) {
Expand All @@ -177,15 +177,6 @@ impl ConfigOptConstruct {
// pub fn is_complete(&self) -> bool {
// #configopt_is_complete
// }

pub fn maybe_generate_config_file_and_exit(&mut self) {
#handle_config_files_generate
}


pub fn patch_with_config_files(&mut self) -> std::result::Result<&mut #configopt_ident, ::std::io::Error> {
#handle_config_files_patch
}
}

// #lints
Expand All @@ -204,18 +195,26 @@ impl ConfigOptConstruct {
// }

#lints
impl ::configopt::ConfigOpt for #configopt_ident {}
impl ::std::convert::TryFrom<&::std::path::Path> for #configopt_ident {
type Error = ::std::io::Error;

#lints
impl ::configopt::ConfigOpt for #ident {}
fn try_from(path: &::std::path::Path) -> ::std::result::Result<Self, Self::Error> {
let contents = ::std::fs::read_to_string(path)?;
Ok(::toml::from_str(&contents)?)
}
}

#lints
impl ::configopt::TomlConfigGenerator for #configopt_ident {
fn toml_config_with_prefix(&self, serde_prefix: &[String]) -> String {
use ::structopt::StructOpt;
impl<T: ::std::convert::AsRef<::std::path::Path>> ::std::convert::TryFrom<&[T]> for #configopt_ident {
type Error = ::std::io::Error;

let app = #ident::clap();
#toml_config_generator_with_prefix
fn try_from(paths: &[T]) -> ::std::result::Result<Self, Self::Error> {
let mut result = #configopt_ident::default();
for path in paths {
let mut other = #configopt_ident::try_from(path.as_ref())?;
result.take(&mut other);
}
Ok(result)
}
}

Expand All @@ -232,26 +231,27 @@ impl ConfigOptConstruct {
}

#lints
impl ::std::convert::TryFrom<&::std::path::Path> for #configopt_ident {
type Error = ::std::io::Error;
impl ::configopt::ConfigOptType for #configopt_ident {
fn maybe_generate_config_file_and_exit(&mut self) {
#handle_config_files_generate
}

fn try_from(path: &::std::path::Path) -> ::std::result::Result<Self, Self::Error> {
let contents = ::std::fs::read_to_string(path)?;
Ok(::toml::from_str(&contents)?)
fn patch_with_config_files(&mut self) -> std::result::Result<&mut #configopt_ident, ::std::io::Error> {
#handle_config_files_patch
}

fn toml_config_with_prefix(&self, serde_prefix: &[String]) -> String {
let app = #ident::clap();
#toml_config_generator_with_prefix
}
}

#lints
impl<T: ::std::convert::AsRef<::std::path::Path>> ::std::convert::TryFrom<&[T]> for #configopt_ident {
type Error = ::std::io::Error;
impl ::configopt::ConfigOpt for #ident {
type ConfigOptType = #configopt_ident;

fn try_from(paths: &[T]) -> ::std::result::Result<Self, Self::Error> {
let mut result = #configopt_ident::default();
for path in paths {
let mut other = #configopt_ident::try_from(path.as_ref())?;
result.take(&mut other);
}
Ok(result)
fn take(&mut self, configopt: &mut Self::ConfigOptType) {
configopt.take_for(self)
}
}
}
Expand All @@ -265,39 +265,47 @@ impl ConfigOptConstruct {
generate::configopt_defaults::for_enum(&parsed_variants);
quote! {
#lints
impl #configopt_ident {
pub fn maybe_generate_config_file_and_exit(&mut self) {
impl ::configopt::ConfigOptDefaults for #configopt_ident {
fn arg_default(&self, arg_path: &[String]) -> Option<::std::ffi::OsString> {
match self {
#configopt_defaults_variant
_ => None,
}
}
}

#lints
impl ::configopt::ConfigOptType for #configopt_ident {
fn maybe_generate_config_file_and_exit(&mut self) {
match self {
#handle_config_files_generate
_ => {}
}
}


pub fn patch_with_config_files(&mut self) -> std::result::Result<&mut #configopt_ident, ::std::io::Error> {
fn patch_with_config_files(&mut self) -> std::result::Result<&mut #configopt_ident, ::std::io::Error> {
match self {
#handle_config_files_patch
_ => {}
}
Ok(self)
}
}

#lints
impl ::configopt::ConfigOpt for #configopt_ident {}
fn toml_config_with_prefix(&self, serde_prefix: &[String]) -> String {
todo!()
}
}

#lints
impl ::configopt::ConfigOpt for #ident {}
impl ::configopt::ConfigOpt for #ident {
type ConfigOptType = #configopt_ident;

#lints
impl ::configopt::ConfigOptDefaults for #configopt_ident {
fn arg_default(&self, arg_path: &[String]) -> Option<::std::ffi::OsString> {
match self {
#configopt_defaults_variant
_ => None,
}
fn take(&mut self, configopt: &mut Self::ConfigOptType) {
todo!()
}
}

}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub fn for_struct(fields: &[ParsedField]) -> TokenStream {
let normal_fields = fields.iter().filter(|f| !f.flatten() && !f.subcommand());
let normal_fields = normal_fields
.map(|field| {
let arg_name = field.serde_name();
let arg_name = field.structopt_name();
let to_default = to_default(field);
quote! {
#arg_name => #to_default,
Expand Down Expand Up @@ -137,7 +137,6 @@ pub fn for_enum(variants: &[ParsedVariant]) -> TokenStream {
let full_configopt_ident = variant.full_configopt_ident();
let span = variant.span();
let structopt_name = variant.structopt_name();
// TODO: Handle other variants
match variant.field_type() {
FieldType::Unit => {
quote_spanned! {span=>
Expand All @@ -153,7 +152,7 @@ pub fn for_enum(variants: &[ParsedVariant]) -> TokenStream {
}
FieldType::Named => {
quote_spanned! {span=>
// TODO
// TODO: Actually lookup the values
#full_configopt_ident{..} => None,
}
}
Expand Down
72 changes: 46 additions & 26 deletions configopt-derive/src/configopt_type/generate/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ pub fn take(fields: &[ParsedField], other: &Ident) -> TokenStream {
} else {
match field.structopt_ty() {
StructOptTy::Vec => quote_spanned! {span=>
// TODO: Should it be wrapped in `Option`?
if !#other_field.is_empty() {
::std::mem::swap(&mut #self_field, &mut #other_field);
}
},
StructOptTy::Bool | StructOptTy::Option
StructOptTy::Bool
| StructOptTy::Option
| StructOptTy::OptionOption
| StructOptTy::OptionVec
| StructOptTy::Other => {
Expand Down Expand Up @@ -54,12 +54,12 @@ pub fn patch(fields: &[ParsedField], other: &Ident) -> TokenStream {
} else {
match field.structopt_ty() {
StructOptTy::Vec => quote_spanned! {span=>
// TODO: Should it be wrapped in `Option`?
if #self_field.is_empty() {
::std::mem::swap(&mut #self_field, &mut #other_field);
}
},
StructOptTy::Bool | StructOptTy::Option
StructOptTy::Bool
| StructOptTy::Option
| StructOptTy::OptionOption
| StructOptTy::OptionVec
| StructOptTy::Other => {
Expand All @@ -75,28 +75,48 @@ pub fn patch(fields: &[ParsedField], other: &Ident) -> TokenStream {
.collect()
}

// fn merge(fields: &[ParsedField]) -> TokenStream {
// fields
// .iter()
// .map(|field| {
// let ident = field.ident();
// let span = field.span();
// if field.flatten() {
// quote_spanned! {span=>
// if let Some(mut val) = self.#ident.take() {
// val.merge(&mut other.#ident)
// }
// }
// } else {
// quote_spanned! {span=>
// if let Some(val) = self.#ident.take() {
// other.#ident = val;
// }
// }
// }
// })
// .collect()
// }
pub fn take_for(fields: &[ParsedField], other: &Ident) -> TokenStream {
fields
.iter()
.map(|field| {
let field_ident = field.ident();
let span = field.span();
let self_field = quote! {self.#field_ident};
let other_field = quote! {#other.#field_ident};
if field.flatten() {
quote_spanned! {span=>
#self_field.take_for(&mut #other_field);
}
} else if field.subcommand() {
quote_spanned! {span=>
// TODO
}
} else {
match field.structopt_ty() {
StructOptTy::Vec => quote_spanned! {span=>
if !#self_field.is_empty() {
::std::mem::swap(&mut #other_field, &mut #self_field);
}
},
StructOptTy::Option | StructOptTy::OptionOption | StructOptTy::OptionVec => {
quote_spanned! {span=>
if #self_field.is_some() {
#other_field = #self_field.take();
}
}
}
StructOptTy::Bool | StructOptTy::Other => {
quote_spanned! {span=>
if let Some(value) = #self_field.take() {
#other_field = value;
}
}
}
}
}
})
.collect()
}

// fn clear(fields: &[ParsedField]) -> TokenStream {
// fields
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ pub fn generate_for_struct(parsed: &[ParsedField]) -> TokenStream {
quote! {
if self.generate_config.unwrap_or_default() {
use ::std::io::Write;
use ::configopt::TomlConfigGenerator;
let out = ::std::io::stdout();
writeln!(&mut out.lock(), "{}", self.toml_config()).expect("Error writing Error to stdout");
::std::process::exit(0);
Expand Down
2 changes: 0 additions & 2 deletions configopt/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# ConfigOpt

TODO
Loading

0 comments on commit 0a6916d

Please sign in to comment.