Repository: kbknapp/clap-rs
Pull request #1311 (2018-06-30 16:20:54)

refactor: Changed the custom derive traits


<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/kbknapp/clap-rs/1311)
<!-- Reviewable:end -->



Patch:
diff --git a/.travis.yml b/.travis.yml
index 367577e8..1e3cfea7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@ language: rust
 cache: cargo
 rust:
   - nightly
-  - nightly-2018-06-19
+  - nightly-2017-10-11
   - beta
   - stable
   - 1.20.0
diff --git a/Cargo.toml b/Cargo.toml
index 92db6314..ae4719c4 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,7 +42,7 @@ A simple to use, efficient, and full featured Command Line Argument Parser
 [badges]
 travis-ci = { repository = "kbknapp/clap-rs" }
 appveyor = { repository = "kbknapp/clap-rs" }
-coveralls = { repository = "kbknapp/clap-rs", branch = "master" }
+coveralls = { repostiory = "kbknapp/clap-rs", branch = "master" }
 is-it-maintained-issue-resolution = { repository = "kbknapp/clap-rs" }
 is-it-maintained-open-issues = { repository = "kbknapp/clap-rs" }
 maintenance = {status = "actively-developed"}
diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs
index 61b0262e..5127c493 100644
--- a/src/build/app/mod.rs
+++ b/src/build/app/mod.rs
@@ -1893,8 +1893,6 @@ impl<'a, 'b> App<'a, 'b> {
             Shell::Fish => format!("{}.fish", name),
             Shell::Zsh => format!("_{}", name),
             Shell::PowerShell => format!("_{}.ps1", name),
-            Shell::Elvish => format!("{}.elv", name),
-            _ => panic!("Unsupported shell type for completion generation")
         };
 
         let mut file = match File::create(out_dir.join(file_name)) {
diff --git a/src/completions/elvish.rs b/src/completions/elvish.rs
deleted file mode 100644
index ec50479b..00000000
--- a/src/completions/elvish.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-// Std
-use std::io::Write;
-
-// Internal
-use build::App;
-use INTERNAL_ERROR_MSG;
-
-pub struct ElvishGen<'a, 'b, 'c>
-where
-    'a: 'b,
-    'b: 'c
-{
-    app: &'c App<'a, 'b>,
-}
-
-impl<'a, 'b, 'c> ElvishGen<'a, 'b, 'c> {
-    pub fn new(p: &'c App<'a, 'b>) -> Self { ElvishGen { app: p } }
-
-    pub fn generate_to<W: Write>(&self, buf: &mut W) {
-        let bin_name = self.app.bin_name.as_ref().unwrap();
-
-        let mut names = vec![];
-        let subcommands_cases =
-            generate_inner(self.app, "", &mut names);
-
-        let result = format!(r#"
-edit:completion:arg-completer[{bin_name}] = [@words]{{
-    fn spaces [n]{{
-        repeat $n ' ' | joins ''
-    }}
-    fn cand [text desc]{{
-        edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc
-    }}
-    command = '{bin_name}'
-    for word $words[1:-1] {{
-        if (has-prefix $word '-') {{
-            break
-        }}
-        command = $command';'$word
-    }}
-    completions = [{subcommands_cases}
-    ]
-    $completions[$command]
-}}
-"#,
-            bin_name = bin_name,
-            subcommands_cases = subcommands_cases
-        );
-
-        w!(buf, result.as_bytes());
-    }
-}
-
-// Escape string inside single quotes
-fn escape_string(string: &str) -> String { string.replace("'", "''") }
-
-fn get_tooltip<T : ToString>(help: Option<&str>, data: T) -> String {
-    match help {
-        Some(help) => escape_string(help),
-        _ => data.to_string()
-    }
-}
-
-fn generate_inner<'a, 'b, 'c>(
-    p: &'c App<'a, 'b>,
-    previous_command_name: &str,
-    names: &mut Vec<&'a str>,
-) -> String where 'a: 'b, 'b: 'c{
-    debugln!("ElvishGen::generate_inner;");
-    let command_name = if previous_command_name.is_empty() {
-        p.bin_name.as_ref().expect(INTERNAL_ERROR_MSG).clone()
-    } else {
-        format!("{};{}", previous_command_name, &p.name)
-    };
-
-    let mut completions = String::new();
-    let preamble = String::from("\n            cand ");
-
-    for option in opts!(p) {
-        if let Some(data) = option.short {
-            let tooltip = get_tooltip(option.help, data);
-            completions.push_str(&preamble);
-            completions.push_str(format!("-{} '{}'", data, tooltip).as_str());
-        }
-        if let Some(data) = option.long {
-            let tooltip = get_tooltip(option.help, data);
-            completions.push_str(&preamble);
-            completions.push_str(format!("--{} '{}'", data, tooltip).as_str());
-        }
-    }
-
-    for flag in flags!(p) {
-        if let Some(data) = flag.short {
-            let tooltip = get_tooltip(flag.help, data);
-            completions.push_str(&preamble);
-            completions.push_str(format!("-{} '{}'", data, tooltip).as_str());
-        }
-        if let Some(data) = flag.long {
-            let tooltip = get_tooltip(flag.help, data);
-            completions.push_str(&preamble);
-            completions.push_str(format!("--{} '{}'", data, tooltip).as_str());
-        }
-    }
-
-    for subcommand in &p.subcommands {
-        let data = &subcommand.name;
-        let tooltip = get_tooltip(subcommand.about, data);
-        completions.push_str(&preamble);
-        completions.push_str(format!("{} '{}'", data, tooltip).as_str());
-    }
-
-    let mut subcommands_cases = format!(
-        r"
-        &'{}'= {{{}
-        }}",
-        &command_name,
-        completions
-    );
-
-    for subcommand in &p.subcommands {
-        let subcommand_subcommands_cases =
-            generate_inner(&subcommand, &command_name, names);
-        subcommands_cases.push_str(&subcommand_subcommands_cases);
-    }
-
-    subcommands_cases
-}
diff --git a/src/completions/mod.rs b/src/completions/mod.rs
index b08cc266..febc9f9e 100644
--- a/src/completions/mod.rs
+++ b/src/completions/mod.rs
@@ -4,7 +4,6 @@ mod bash;
 mod fish;
 mod zsh;
 mod powershell;
-mod elvish;
 mod shell;
 
 // Std
@@ -16,7 +15,6 @@ use self::bash::BashGen;
 use self::fish::FishGen;
 use self::zsh::ZshGen;
 use self::powershell::PowerShellGen;
-use self::elvish::ElvishGen;
 pub use self::shell::Shell;
 
 pub struct ComplGen<'a, 'b>(&'b App<'a, 'b>)
@@ -32,8 +30,6 @@ impl<'a, 'b> ComplGen<'a, 'b> {
             Shell::Fish => FishGen::new(self.0).generate_to(buf),
             Shell::Zsh => ZshGen::new(self.0).generate_to(buf),
             Shell::PowerShell => PowerShellGen::new(self.0).generate_to(buf),
-            Shell::Elvish => ElvishGen::new(self.0).generate_to(buf),
-            _ => panic!("Unsupported shell type for generating completions")
         }
     }
 }
diff --git a/src/completions/shell.rs b/src/completions/shell.rs
index b1f13167..75b7d360 100644
--- a/src/completions/shell.rs
+++ b/src/completions/shell.rs
@@ -15,15 +15,11 @@ pub enum Shell {
     Zsh,
     /// Generates a completion file for PowerShell
     PowerShell,
-    /// Generates a completion file for Elvish
-    Elvish,
-    #[doc(hidden)]
-    __Nonexhaustive,
 }
 
 impl Shell {
     /// A list of possible variants in `&'static str` form
-    pub fn variants() -> [&'static str; 5] { ["zsh", "bash", "fish", "powershell", "elvish"] }
+    pub fn variants() -> [&'static str; 4] { ["zsh", "bash", "fish", "powershell"] }
 }
 
 impl FromStr for Shell {
@@ -35,8 +31,7 @@ impl FromStr for Shell {
             "FISH" | _ if s.eq_ignore_ascii_case("fish") => Ok(Shell::Fish),
             "BASH" | _ if s.eq_ignore_ascii_case("bash") => Ok(Shell::Bash),
             "POWERSHELL" | _ if s.eq_ignore_ascii_case("powershell") => Ok(Shell::PowerShell),
-            "ELVISH" | _ if s.eq_ignore_ascii_case("elvish") => Ok(Shell::Elvish),
-            _ => Err(String::from("[valid values: bash, fish, zsh, powershell, elvish]")),
+            _ => Err(String::from("[valid values: bash, fish, zsh, powershell]")),
         }
     }
 }
@@ -48,8 +43,6 @@ impl fmt::Display for Shell {
             Shell::Fish => write!(f, "FISH"),
             Shell::Zsh => write!(f, "ZSH"),
             Shell::PowerShell => write!(f, "POWERSHELL"),
-            Shell::Elvish => write!(f, "ELVISH"),
-            _ => panic!("Unsupported shell type for completion generation")
         }
     }
 }
diff --git a/src/lib.rs b/src/lib.rs
index 5a5d4a1f..bfda078f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -574,7 +574,10 @@ pub use derive::{ArgEnum, ClapApp, FromArgMatches, IntoApp};
 #[cfg(unstable)]
 mod derive {
     /// @TODO @release @docs
-    pub trait ClapApp: IntoApp + FromArgMatches + Sized {
+    pub trait Clap: IntoApp + FromArgMatches + Parse + Sized {}
+
+    /// @TODO @release @docs
+    pub trait Parse {
         /// @TODO @release @docs
         fn parse() -> Self { Self::from_argmatches(Self::into_app().get_matches()) }
 
diff --git a/src/parse/matches/arg_matches.rs b/src/parse/matches/arg_matches.rs
index dda7a579..17523d22 100644
--- a/src/parse/matches/arg_matches.rs
+++ b/src/parse/matches/arg_matches.rs
@@ -858,8 +858,6 @@ impl<'a> DoubleEndedIterator for OsValues<'a> {
     fn next_back(&mut self) -> Option<&'a OsStr> { self.iter.next_back() }
 }
 
-impl<'a> ExactSizeIterator for OsValues<'a> {}
-
 /// Creates an empty iterator.
 impl<'a> Default for OsValues<'a> {
     fn default() -> Self {


Test patch:
diff --git a/tests/completions.rs b/tests/completions.rs
index f2ab7ac3..03c38b17 100644
--- a/tests/completions.rs
+++ b/tests/completions.rs
@@ -228,105 +228,6 @@ Register-ArgumentCompleter -Native -CommandName 'my_app' -ScriptBlock {
 }
 "#;
 
-static ELVISH: &'static str = r#"
-edit:completion:arg-completer[my_app] = [@words]{
-    fn spaces [n]{
-        repeat $n ' ' | joins ''
-    }
-    fn cand [text desc]{
-        edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc
-    }
-    command = 'my_app'
-    for word $words[1:-1] {
-        if (has-prefix $word '-') {
-            break
-        }
-        command = $command';'$word
-    }
-    completions = [
-        &'my_app'= {
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-            cand test 'tests things'
-            cand help 'Prints this message or the help of the given subcommand(s)'
-        }
-        &'my_app;test'= {
-            cand --case 'the case to test'
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-        }
-        &'my_app;help'= {
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-        }
-    ]
-    $completions[$command]
-}
-"#;
-
-static ELVISH_SPECIAL_CMDS: &'static str = r#"
-edit:completion:arg-completer[my_app] = [@words]{
-    fn spaces [n]{
-        repeat $n ' ' | joins ''
-    }
-    fn cand [text desc]{
-        edit:complex-candidate $text &display-suffix=' '(spaces (- 14 (wcswidth $text)))$desc
-    }
-    command = 'my_app'
-    for word $words[1:-1] {
-        if (has-prefix $word '-') {
-            break
-        }
-        command = $command';'$word
-    }
-    completions = [
-        &'my_app'= {
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-            cand test 'tests things'
-            cand some_cmd 'tests other things'
-            cand some-cmd-with-hypens 'some-cmd-with-hypens'
-            cand help 'Prints this message or the help of the given subcommand(s)'
-        }
-        &'my_app;test'= {
-            cand --case 'the case to test'
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-        }
-        &'my_app;some_cmd'= {
-            cand --config 'the other case to test'
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-        }
-        &'my_app;some-cmd-with-hypens'= {
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-        }
-        &'my_app;help'= {
-            cand -h 'Prints help information'
-            cand --help 'Prints help information'
-            cand -V 'Prints version information'
-            cand --version 'Prints version information'
-        }
-    ]
-    $completions[$command]
-}
-"#;
-
 static POWERSHELL_SPECIAL_CMDS: &'static str = r#"
 using namespace System.Management.Automation
 using namespace System.Management.Automation.Language
@@ -802,26 +703,6 @@ fn powershell() {
     assert!(compare(&*string, POWERSHELL));
 }
 
-#[test]
-fn elvish() {
-    let mut app = build_app();
-    let mut buf = vec![];
-    app.gen_completions_to("my_app", Shell::Elvish, &mut buf);
-    let string = String::from_utf8(buf).unwrap();
-
-    assert!(compare(&*string, ELVISH));
-}
-
-#[test]
-fn elvish_with_special_commands() {
-    let mut app = build_app_special_commands();
-    let mut buf = vec![];
-    app.gen_completions_to("my_app", Shell::Elvish, &mut buf);
-    let string = String::from_utf8(buf).unwrap();
-
-    assert!(compare(&*string, ELVISH_SPECIAL_CMDS));
-}
-
 #[test]
 fn powershell_with_special_commands() {
     let mut app = build_app_special_commands();