-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH 731 review #341
GH 731 review #341
Changes from 8 commits
cedb1b3
32dd2cb
690b099
0d7427b
22e607b
b9a6e85
08349e2
8aead2a
6167856
7286ee8
fce6fe1
4dd0932
413ffc5
18d0cc1
efd3fbb
cf6da59
34b8fea
5895879
62e99e3
8369ff9
5b02822
0603f70
2ec7e12
fe491ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,6 +50,7 @@ macro_rules! values_m { | |
#[derive(Debug)] | ||
pub struct MultiConfig<'a> { | ||
arg_matches: ArgMatches<'a>, | ||
computed_value_names: HashSet<String> | ||
} | ||
|
||
impl<'a> MultiConfig<'a> { | ||
|
@@ -61,24 +62,41 @@ impl<'a> MultiConfig<'a> { | |
schema: &App<'a, 'a>, | ||
vcls: Vec<Box<dyn VirtualCommandLine>>, | ||
) -> Result<MultiConfig<'a>, ConfiguratorError> { | ||
let mut computed_value_names = HashSet::new(); | ||
let initial: Box<dyn VirtualCommandLine> = | ||
Box::new(CommandLineVcl::new(vec![String::new()])); | ||
let merged: Box<dyn VirtualCommandLine> = vcls | ||
.into_iter() | ||
.fold(initial, |so_far, vcl| merge(so_far, vcl)); | ||
let vlc_copy = &vcls; | ||
czarte marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
vlc_copy.into_iter().for_each(|vcl| { | ||
vcl.vcl_args().iter().for_each(|vcl_arg| { | ||
match vcl.is_computed() { | ||
true => computed_value_names.insert(vcl_arg.name().to_string()), | ||
false => computed_value_names.remove(&vcl_arg.name().to_string()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't say, with the knowledge in my head, whether removing this value from the I'm not suggesting that this code doesn't work; I'm unsure whether the situation it creates is the one we want. Example: if the user specifies the |
||
}; | ||
}) | ||
}); | ||
} | ||
let merged: Box<dyn VirtualCommandLine> = vcls.into_iter().fold(initial, |so_far, vcl | -> Box<dyn VirtualCommandLine> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might not need to specify the return type for the closure. If you do, go ahead, but it seems to me that the definition of |
||
merge(so_far, vcl) | ||
}); | ||
|
||
let arg_matches = match schema | ||
.clone() | ||
.get_matches_from_safe(merged.args().into_iter()) | ||
{ | ||
Ok(matches) => matches, | ||
Err(e) => match e.kind { | ||
clap::ErrorKind::HelpDisplayed | clap::ErrorKind::VersionDisplayed => { | ||
unreachable!("The program's entry check failed to catch this.") | ||
Ok(matches) => { | ||
matches | ||
}, | ||
Err(e) => { | ||
match e.kind { | ||
clap::ErrorKind::HelpDisplayed | clap::ErrorKind::VersionDisplayed => { | ||
unreachable!("The program's entry check failed to catch this.") | ||
} | ||
_ => return Err(Self::make_configurator_error(e)), | ||
} | ||
_ => return Err(Self::make_configurator_error(e)), | ||
}, | ||
}; | ||
Ok(MultiConfig { arg_matches }) | ||
Ok(MultiConfig { arg_matches, computed_value_names }) | ||
} | ||
|
||
fn check_for_invalid_value_err( | ||
|
@@ -139,6 +157,13 @@ impl<'a> MultiConfig<'a> { | |
ConfiguratorError::required("<unknown>", &format!("Unfamiliar message: {}", e.message)) | ||
} | ||
|
||
pub fn is_user_specified(&self, value_name: &str) -> bool { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the old code, there's a macro that looks like this:
That seems incompatible with this code. Do the two pass the same tests? Further observation: The macro above does not seem to be used anywhere in the codebase anymore. (Check to make sure I'm right about this.) If it's not, there's no need to keep it around, and once it's deleted its meaning can be redefined as desired. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
match self.computed_value_names.contains(value_name) { | ||
czarte marked this conversation as resolved.
Show resolved
Hide resolved
|
||
true => false, | ||
false => true | ||
} | ||
} | ||
|
||
pub fn occurrences_of(&self, parameter: &str) -> u64 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At this point, I think we can remove There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm afraid it is not possible. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Next thing is |
||
self.arg_matches.occurrences_of(parameter) | ||
} | ||
|
@@ -224,6 +249,7 @@ impl NameOnlyVclArg { | |
pub trait VirtualCommandLine { | ||
fn vcl_args(&self) -> Vec<&dyn VclArg>; | ||
fn args(&self) -> Vec<String>; | ||
fn is_computed(&self) -> bool { false } | ||
} | ||
|
||
impl Debug for dyn VirtualCommandLine { | ||
|
@@ -263,6 +289,24 @@ pub fn merge( | |
}) | ||
} | ||
|
||
pub struct ComputedVcl { | ||
vcl_args: Vec<Box<dyn VclArg>>, | ||
} | ||
|
||
impl VirtualCommandLine for ComputedVcl { | ||
fn vcl_args(&self) -> Vec<&dyn VclArg> { | ||
vcl_args_to_vcl_args(&self.vcl_args) | ||
czarte marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
fn args(&self) -> Vec<String> { | ||
vcl_args_to_args(&self.vcl_args) | ||
} | ||
|
||
fn is_computed(&self) -> bool { | ||
true | ||
} | ||
} | ||
|
||
pub struct CommandLineVcl { | ||
vcl_args: Vec<Box<dyn VclArg>>, | ||
} | ||
|
@@ -283,6 +327,33 @@ impl From<Vec<Box<dyn VclArg>>> for CommandLineVcl { | |
} | ||
} | ||
|
||
impl ComputedVcl { | ||
czarte marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub fn new(mut args: Vec<String>) -> ComputedVcl { | ||
args.remove(0); // remove command | ||
let mut vcl_args = vec![]; | ||
while let Some(vcl_arg) = Self::next_vcl_arg(&mut args) { | ||
vcl_args.push(vcl_arg); | ||
} | ||
ComputedVcl { vcl_args } | ||
} | ||
|
||
fn next_vcl_arg(args: &mut Vec<String>) -> Option<Box<dyn VclArg>> { | ||
if args.is_empty() { | ||
return None; | ||
} | ||
let name = args.remove(0); | ||
if !name.starts_with("--") { | ||
panic!("Expected option beginning with '--', not {}", name) | ||
} | ||
if args.is_empty() || args[0].starts_with("--") { | ||
Some(Box::new(NameOnlyVclArg::new(&name))) | ||
} else { | ||
let value = args.remove(0); | ||
Some(Box::new(NameValueVclArg::new(&name, &value))) | ||
} | ||
} | ||
} | ||
|
||
impl CommandLineVcl { | ||
pub fn new(mut args: Vec<String>) -> CommandLineVcl { | ||
args.remove(0); // remove command | ||
|
@@ -347,6 +418,7 @@ impl EnvironmentVcl { | |
} | ||
} | ||
|
||
#[derive(Debug)] | ||
pub struct ConfigFileVcl { | ||
vcl_args: Vec<Box<dyn VclArg>>, | ||
} | ||
|
@@ -360,6 +432,16 @@ impl VirtualCommandLine for ConfigFileVcl { | |
vcl_args_to_args(&self.vcl_args) | ||
} | ||
} | ||
/* | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Commented-out code |
||
impl VirtualCommandLine for dyn VclArg { | ||
fn vcl_args(&self) -> Vec<&dyn VclArg> { | ||
vcl_args_to_vcl_args(&[Box::new(self.vcl_args().as_slice())]) | ||
} | ||
|
||
fn args(&self) -> Vec<String> { | ||
vcl_args_to_args(&[Box::new(self.vcl_args().as_slice())]) | ||
} | ||
}*/ | ||
|
||
#[derive(Debug)] | ||
pub enum ConfigFileVclError { | ||
|
@@ -491,8 +573,14 @@ fn append<T>(ts: Vec<T>, t: T) -> Vec<T> { | |
|
||
#[cfg(not(feature = "no_test_share"))] | ||
impl<'a> MultiConfig<'a> { | ||
pub fn new_test_only(arg_matches: ArgMatches<'a>) -> Self { | ||
Self { arg_matches } | ||
pub fn new_test_only( | ||
arg_matches: ArgMatches<'a>, | ||
computed_value_names: HashSet<String> | ||
) -> Self { | ||
Self { | ||
arg_matches, | ||
computed_value_names | ||
} | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this down so that it's next to where it's used? It'd be easier to read.