Skip to content

Commit

Permalink
feat(Subcommands): adds support for subcommands from yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
kbknapp committed Sep 1, 2015
1 parent 86cf4c4 commit e415cf7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 12 deletions.
47 changes: 35 additions & 12 deletions src/app/app.rs
Expand Up @@ -158,43 +158,66 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
/// let app = App::from_yaml(yml);
/// ```
#[cfg(feature = "yaml")]
pub fn from_yaml<'y>(doc: &'y Yaml) -> App<'y, 'y, 'y, 'y, 'y, 'y> {
pub fn from_yaml<'y>(mut yaml: &'y Yaml) -> App<'y, 'y, 'y, 'y, 'y, 'y> {
// We WANT this to panic on error...so expect() is good.
let mut a = App::new(doc["name"].as_str().unwrap());
if let Some(v) = doc["version"].as_str() {
let mut is_sc = None;
let mut a = if let Some(name) = yaml["name"].as_str() {
App::new(name)
} else {
let yaml_hash = yaml.as_hash().unwrap();
let sc_key = yaml_hash.keys().nth(0).unwrap();
is_sc = Some(yaml_hash.get(sc_key).unwrap());
App::new(sc_key.as_str().unwrap())
};
yaml = if let Some(sc) = is_sc {
sc
} else {
yaml
};
if let Some(v) = yaml["version"].as_str() {
a = a.version(v);
}
if let Some(v) = doc["author"].as_str() {
if let Some(v) = yaml["author"].as_str() {
a = a.author(v);
}
if let Some(v) = doc["bin_name"].as_str() {
if let Some(v) = yaml["bin_name"].as_str() {
a = a.bin_name(v);
}
if let Some(v) = doc["about"].as_str() {
if let Some(v) = yaml["about"].as_str() {
a = a.about(v);
}
if let Some(v) = doc["after_help"].as_str() {
if let Some(v) = yaml["after_help"].as_str() {
a = a.after_help(v);
}
if let Some(v) = doc["usage"].as_str() {
if let Some(v) = yaml["usage"].as_str() {
a = a.usage(v);
}
if let Some(v) = doc["help"].as_str() {
if let Some(v) = yaml["help"].as_str() {
a = a.help(v);
}
if let Some(v) = doc["help_short"].as_str() {
if let Some(v) = yaml["help_short"].as_str() {
a = a.help_short(v);
}
if let Some(v) = doc["version_short"].as_str() {
if let Some(v) = yaml["version_short"].as_str() {
a = a.version_short(v);
}
if let Some(v) = doc["settings"].as_vec() {
if let Some(v) = yaml["settings"].as_vec() {
for ys in v {
if let Some(s) = ys.as_str() {
a = a.setting(s.parse().ok().expect("unknown AppSetting found in YAML file"));
}
}
}
if let Some(v) = yaml["args"].as_vec() {
for arg_yaml in v {
a = a.arg(Arg::from_yaml(&arg_yaml.as_hash().unwrap()));
}
}
if let Some(v) = yaml["subcommands"].as_vec() {
for sc_yaml in v {
a = a.subcommand(SubCommand::from_yaml(&sc_yaml));
}
}

a
}
Expand Down
17 changes: 17 additions & 0 deletions src/args/subcommand.rs
@@ -1,3 +1,6 @@
#[cfg(feature = "yaml")]
use yaml_rust::Yaml;

use App;
use ArgMatches;

Expand Down Expand Up @@ -42,4 +45,18 @@ impl<'n, 'a> SubCommand<'n, 'a> {
pub fn with_name<'au, 'v, 'ab, 'u, 'h, 'ar>(name: &'ar str) -> App<'au, 'v, 'ab, 'u, 'h, 'ar> {
App::new(name)
}

/// Creates a new instance of a subcommand from a YAML (.yml) document
///
/// # Example
///
/// ```ignore
/// # use clap::{App, Arg, SubCommand};
/// let sc_yaml = load_yaml!("test_subcommand.yml");
/// let sc = SubCommand::from_yaml(sc_yaml);
/// ```
#[cfg(feature = "yaml")]
pub fn from_yaml<'y>(yaml: &'y Yaml) -> App<'y, 'y, 'y, 'y, 'y, 'y> {
App::from_yaml(yaml)
}
}

0 comments on commit e415cf7

Please sign in to comment.