diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4725c60e..541185da 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,23 +1,23 @@
-## 2.28.0 (2017-11-27)
+## 2.28.0 (2017-11-28)
The minimum required Rust is now 1.20. This was done to start using bitflags 1.0 and having >1.0 deps is a *very good* thing!
+#### Documentation
-#### API Additions
-
-* Adds the traits to be used with the `clap-derive` crate to be able to use Custom Derive ([6f4c3412](https://github.com/kbknapp/clap-rs/commit/6f4c3412415e882f5ca2cc3fbd6d4dce79440828))
+* changes the demo version to 2.28 to stay in sync ([ce6ca492](https://github.com/kbknapp/clap-rs/commit/ce6ca492c7510ab6474075806360b96081b021a9))
+* Fix URL path to github hosted files ([ce72aada](https://github.com/kbknapp/clap-rs/commit/ce72aada56a9581d4a6cb4bf9bdb861c3906f8df), closes [#1106](https://github.com/kbknapp/clap-rs/issues/1106))
+* fix typo ([002b07fc](https://github.com/kbknapp/clap-rs/commit/002b07fc98a1c85acb66296b1eec0b2aba906125))
+* **README.md:** updates the readme and pulls out some redundant sections ([db6caf86](https://github.com/kbknapp/clap-rs/commit/db6caf8663747e679d2f4ed3bd127f33476754aa))
#### Improvements
* adds '[SUBCOMMAND]' to usage strings with only AppSettings::AllowExternalSubcommands is used with no other subcommands ([e78bb757](https://github.com/kbknapp/clap-rs/commit/e78bb757a3df16e82d539e450c06767a6bfcf859), closes [#1093](https://github.com/kbknapp/clap-rs/issues/1093))
-* uses `.bash` for Bash completion scripts now instead of `.bash-completion` due to convention and `.bash-completion` not being supported by completion projects ([4740cde4](https://github.com/kbknapp/clap-rs/commit/4740cde404121a443c64d644eb4a0722c0b0a823)
-#### Documentation
+#### API Additions
-* Fix URL path to github hosted files ([ce72aada](https://github.com/kbknapp/clap-rs/commit/ce72aada56a9581d4a6cb4bf9bdb861c3906f8df), closes [#1106](https://github.com/kbknapp/clap-rs/issues/1106))
-* fix typo ([002b07fc](https://github.com/kbknapp/clap-rs/commit/002b07fc98a1c85acb66296b1eec0b2aba906125))
-* **README.md:** updates the readme and pulls out some redundant sections ([db6caf86](https://github.com/kbknapp/clap-rs/commit/db6caf8663747e679d2f4ed3bd127f33476754aa))
+* Adds Arg::case_insensitive(bool) which allows matching Arg::possible_values without worrying about ASCII case ([1fec268e](https://github.com/kbknapp/clap-rs/commit/1fec268e51736602e38e67c76266f439e2e0ef12), closes [#1118](https://github.com/kbknapp/clap-rs/issues/1118))
+* Adds the traits to be used with the clap-derive crate to be able to use Custom Derive ([6f4c3412](https://github.com/kbknapp/clap-rs/commit/6f4c3412415e882f5ca2cc3fbd6d4dce79440828))
#### Bug Fixes
@@ -25,7 +25,6 @@ The minimum required Rust is now 1.20. This was done to start using bitflags 1.0
* fixes a bug that allowed options to pass parsing when no value was provided ([2fb75821](https://github.com/kbknapp/clap-rs/commit/2fb758219c7a60d639da67692e100b855a8165ac), closes [#1105](https://github.com/kbknapp/clap-rs/issues/1105))
* ignore PropagateGlobalValuesDown deprecation warning ([f61ce3f5](https://github.com/kbknapp/clap-rs/commit/f61ce3f55fe65e16b3db0bd4facdc4575de22767), closes [#1086](https://github.com/kbknapp/clap-rs/issues/1086))
-
#### Deps
* Updates `bitflags` to 1.0
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 39731d74..d6b83808 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -9,73 +9,77 @@ the following is a list of contributors:
:---: |:---: |:---: |:---: |:---: |:---: |
[willmurphyscode](https://github.com/willmurphyscode) |[mgeisler](https://github.com/mgeisler) |[nabijaczleweli](https://github.com/nabijaczleweli) |[Byron](https://github.com/Byron) |[hgrecco](https://github.com/hgrecco) |[bluejekyll](https://github.com/bluejekyll) |
-[](https://github.com/james-darkfox) |[](https://github.com/H2CO3) |[](https://github.com/nateozem) |[](https://github.com/glowing-chemist) |[](https://github.com/Arnavion) |[](https://github.com/rtaycher) |
+[](https://github.com/ignatenkobrain) |[](https://github.com/james-darkfox) |[](https://github.com/H2CO3) |[](https://github.com/nateozem) |[](https://github.com/glowing-chemist) |[](https://github.com/rtaycher) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[james-darkfox](https://github.com/james-darkfox) |[H2CO3](https://github.com/H2CO3) |[nateozem](https://github.com/nateozem) |[glowing-chemist](https://github.com/glowing-chemist) |[Arnavion](https://github.com/Arnavion) |[rtaycher](https://github.com/rtaycher) |
+[ignatenkobrain](https://github.com/ignatenkobrain) |[james-darkfox](https://github.com/james-darkfox) |[H2CO3](https://github.com/H2CO3) |[nateozem](https://github.com/nateozem) |[glowing-chemist](https://github.com/glowing-chemist) |[rtaycher](https://github.com/rtaycher) |
-[](https://github.com/japaric) |[](https://github.com/untitaker) |[](https://github.com/afiune) |[](https://github.com/crazymerlyn) |[](https://github.com/SuperFluffy) |[](https://github.com/malbarbo) |
+[](https://github.com/Arnavion) |[](https://github.com/japaric) |[](https://github.com/untitaker) |[](https://github.com/afiune) |[](https://github.com/crazymerlyn) |[](https://github.com/SuperFluffy) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[japaric](https://github.com/japaric) |[untitaker](https://github.com/untitaker) |[afiune](https://github.com/afiune) |[crazymerlyn](https://github.com/crazymerlyn) |[SuperFluffy](https://github.com/SuperFluffy) |[malbarbo](https://github.com/malbarbo) |
+[Arnavion](https://github.com/Arnavion) |[japaric](https://github.com/japaric) |[untitaker](https://github.com/untitaker) |[afiune](https://github.com/afiune) |[crazymerlyn](https://github.com/crazymerlyn) |[SuperFluffy](https://github.com/SuperFluffy) |
-[](https://github.com/matthiasbeyer) |[](https://github.com/gohyda) |[](https://github.com/tshepang) |[](https://github.com/golem131) |[](https://github.com/jimmycuadra) |[](https://github.com/Nemo157) |
+[](https://github.com/malbarbo) |[](https://github.com/matthiasbeyer) |[](https://github.com/gohyda) |[](https://github.com/tshepang) |[](https://github.com/golem131) |[](https://github.com/jimmycuadra) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[matthiasbeyer](https://github.com/matthiasbeyer) |[gohyda](https://github.com/gohyda) |[tshepang](https://github.com/tshepang) |[golem131](https://github.com/golem131) |[jimmycuadra](https://github.com/jimmycuadra) |[Nemo157](https://github.com/Nemo157) |
+[malbarbo](https://github.com/malbarbo) |[matthiasbeyer](https://github.com/matthiasbeyer) |[gohyda](https://github.com/gohyda) |[tshepang](https://github.com/tshepang) |[golem131](https://github.com/golem131) |[jimmycuadra](https://github.com/jimmycuadra) |
-[](https://github.com/SShrike) |[](https://github.com/porglezomp) |[](https://github.com/wdv4758h) |[](https://github.com/frewsxcv) |[](https://github.com/hoodie) |[](https://github.com/huonw) |
+[](https://github.com/Nemo157) |[](https://github.com/SShrike) |[](https://github.com/Eijebong) |[](https://github.com/cstorey) |[](https://github.com/wdv4758h) |[](https://github.com/frewsxcv) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[SShrike](https://github.com/SShrike) |[porglezomp](https://github.com/porglezomp) |[wdv4758h](https://github.com/wdv4758h) |[frewsxcv](https://github.com/frewsxcv) |[hoodie](https://github.com/hoodie) |[huonw](https://github.com/huonw) |
+[Nemo157](https://github.com/Nemo157) |[SShrike](https://github.com/SShrike) |[Eijebong](https://github.com/Eijebong) |[cstorey](https://github.com/cstorey) |[wdv4758h](https://github.com/wdv4758h) |[frewsxcv](https://github.com/frewsxcv) |
-[](https://github.com/GrappigPanda) |[](https://github.com/ignatenkobrain) |[](https://github.com/shepmaster) |[](https://github.com/cstorey) |[](https://github.com/kieraneglin) |[](https://github.com/musoke) |
+[](https://github.com/hoodie) |[](https://github.com/huonw) |[](https://github.com/GrappigPanda) |[](https://github.com/shepmaster) |[](https://github.com/porglezomp) |[](https://github.com/kieraneglin) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[GrappigPanda](https://github.com/GrappigPanda) |[ignatenkobrain](https://github.com/ignatenkobrain) |[shepmaster](https://github.com/shepmaster) |[cstorey](https://github.com/cstorey) |[kieraneglin](https://github.com/kieraneglin) |[musoke](https://github.com/musoke) |
+[hoodie](https://github.com/hoodie) |[huonw](https://github.com/huonw) |[GrappigPanda](https://github.com/GrappigPanda) |[shepmaster](https://github.com/shepmaster) |[porglezomp](https://github.com/porglezomp) |[kieraneglin](https://github.com/kieraneglin) |
-[](https://github.com/nelsonjchen) |[](https://github.com/pkgw) |[](https://github.com/Deedasmi) |[](https://github.com/vmchale) |[](https://github.com/messense) |[](https://github.com/Keats) |
+[](https://github.com/musoke) |[](https://github.com/nelsonjchen) |[](https://github.com/pkgw) |[](https://github.com/Deedasmi) |[](https://github.com/vmchale) |[](https://github.com/messense) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[nelsonjchen](https://github.com/nelsonjchen) |[pkgw](https://github.com/pkgw) |[Deedasmi](https://github.com/Deedasmi) |[vmchale](https://github.com/vmchale) |[messense](https://github.com/messense) |[Keats](https://github.com/Keats) |
+[musoke](https://github.com/musoke) |[nelsonjchen](https://github.com/nelsonjchen) |[pkgw](https://github.com/pkgw) |[Deedasmi](https://github.com/Deedasmi) |[vmchale](https://github.com/vmchale) |[messense](https://github.com/messense) |
-[](https://github.com/starkat99) |[](https://github.com/durka) |[](https://github.com/alex-gulyas) |[](https://github.com/cite-reader) |[](https://github.com/alexbool) |[](https://github.com/AluisioASG) |
+[](https://github.com/Keats) |[](https://github.com/starkat99) |[](https://github.com/durka) |[](https://github.com/alex-gulyas) |[](https://github.com/cite-reader) |[](https://github.com/alexbool) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[starkat99](https://github.com/starkat99) |[durka](https://github.com/durka) |[alex-gulyas](https://github.com/alex-gulyas) |[cite-reader](https://github.com/cite-reader) |[alexbool](https://github.com/alexbool) |[AluisioASG](https://github.com/AluisioASG) |
+[Keats](https://github.com/Keats) |[starkat99](https://github.com/starkat99) |[durka](https://github.com/durka) |[alex-gulyas](https://github.com/alex-gulyas) |[cite-reader](https://github.com/cite-reader) |[alexbool](https://github.com/alexbool) |
-[](https://github.com/BurntSushi) |[](https://github.com/nox) |[](https://github.com/pixelistik) |[](https://github.com/brennie) |[](https://github.com/ogham) |[](https://github.com/Bilalh) |
+[](https://github.com/AluisioASG) |[](https://github.com/BurntSushi) |[](https://github.com/nox) |[](https://github.com/pixelistik) |[](https://github.com/brennie) |[](https://github.com/ogham) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[BurntSushi](https://github.com/BurntSushi) |[nox](https://github.com/nox) |[pixelistik](https://github.com/pixelistik) |[brennie](https://github.com/brennie) |[ogham](https://github.com/ogham) |[Bilalh](https://github.com/Bilalh) |
+[AluisioASG](https://github.com/AluisioASG) |[BurntSushi](https://github.com/BurntSushi) |[nox](https://github.com/nox) |[pixelistik](https://github.com/pixelistik) |[brennie](https://github.com/brennie) |[ogham](https://github.com/ogham) |
-[](https://github.com/dotdash) |[](https://github.com/bradurani) |[](https://github.com/Seeker14491) |[](https://github.com/brianp) |[](https://github.com/casey) |[](https://github.com/volks73) |
+[](https://github.com/Bilalh) |[](https://github.com/dotdash) |[](https://github.com/bradurani) |[](https://github.com/Seeker14491) |[](https://github.com/brianp) |[](https://github.com/casey) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[dotdash](https://github.com/dotdash) |[bradurani](https://github.com/bradurani) |[Seeker14491](https://github.com/Seeker14491) |[brianp](https://github.com/brianp) |[casey](https://github.com/casey) |[volks73](https://github.com/volks73) |
+[Bilalh](https://github.com/Bilalh) |[dotdash](https://github.com/dotdash) |[bradurani](https://github.com/bradurani) |[Seeker14491](https://github.com/Seeker14491) |[brianp](https://github.com/brianp) |[casey](https://github.com/casey) |
-[](https://github.com/daboross) |[](https://github.com/mernen) |[](https://github.com/dguo) |[](https://github.com/davidszotten) |[](https://github.com/drusellers) |[](https://github.com/eddyb) |
+[](https://github.com/volks73) |[](https://github.com/daboross) |[](https://github.com/mernen) |[](https://github.com/dguo) |[](https://github.com/davidszotten) |[](https://github.com/drusellers) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[daboross](https://github.com/daboross) |[mernen](https://github.com/mernen) |[dguo](https://github.com/dguo) |[davidszotten](https://github.com/davidszotten) |[drusellers](https://github.com/drusellers) |[eddyb](https://github.com/eddyb) |
+[volks73](https://github.com/volks73) |[daboross](https://github.com/daboross) |[mernen](https://github.com/mernen) |[dguo](https://github.com/dguo) |[davidszotten](https://github.com/davidszotten) |[drusellers](https://github.com/drusellers) |
-[](https://github.com/Fraser999) |[](https://github.com/birkenfeld) |[](https://github.com/guanqun) |[](https://github.com/tanakh) |[](https://github.com/SirVer) |[](https://github.com/idmit) |
+[](https://github.com/eddyb) |[](https://github.com/Fraser999) |[](https://github.com/birkenfeld) |[](https://github.com/guanqun) |[](https://github.com/tanakh) |[](https://github.com/SirVer) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[Fraser999](https://github.com/Fraser999) |[birkenfeld](https://github.com/birkenfeld) |[guanqun](https://github.com/guanqun) |[tanakh](https://github.com/tanakh) |[SirVer](https://github.com/SirVer) |[idmit](https://github.com/idmit) |
+[eddyb](https://github.com/eddyb) |[Fraser999](https://github.com/Fraser999) |[birkenfeld](https://github.com/birkenfeld) |[guanqun](https://github.com/guanqun) |[tanakh](https://github.com/tanakh) |[SirVer](https://github.com/SirVer) |
-[](https://github.com/archer884) |[](https://github.com/jacobmischka) |[](https://github.com/jespino) |[](https://github.com/jtdowney) |[](https://github.com/andete) |[](https://github.com/joshtriplett) |
+[](https://github.com/idmit) |[](https://github.com/archer884) |[](https://github.com/jacobmischka) |[](https://github.com/jespino) |[](https://github.com/jfrankenau) |[](https://github.com/jtdowney) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[archer884](https://github.com/archer884) |[jacobmischka](https://github.com/jacobmischka) |[jespino](https://github.com/jespino) |[jtdowney](https://github.com/jtdowney) |[andete](https://github.com/andete) |[joshtriplett](https://github.com/joshtriplett) |
+[idmit](https://github.com/idmit) |[archer884](https://github.com/archer884) |[jacobmischka](https://github.com/jacobmischka) |[jespino](https://github.com/jespino) |[jfrankenau](https://github.com/jfrankenau) |[jtdowney](https://github.com/jtdowney) |
-[](https://github.com/Kalwyn) |[](https://github.com/manuel-rhdt) |[](https://github.com/Marwes) |[](https://github.com/mdaffin) |[](https://github.com/iliekturtles) |[](https://github.com/nicompte) |
+[](https://github.com/andete) |[](https://github.com/joshtriplett) |[](https://github.com/Kalwyn) |[](https://github.com/manuel-rhdt) |[](https://github.com/Marwes) |[](https://github.com/mdaffin) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[Kalwyn](https://github.com/Kalwyn) |[manuel-rhdt](https://github.com/manuel-rhdt) |[Marwes](https://github.com/Marwes) |[mdaffin](https://github.com/mdaffin) |[iliekturtles](https://github.com/iliekturtles) |[nicompte](https://github.com/nicompte) |
+[andete](https://github.com/andete) |[joshtriplett](https://github.com/joshtriplett) |[Kalwyn](https://github.com/Kalwyn) |[manuel-rhdt](https://github.com/manuel-rhdt) |[Marwes](https://github.com/Marwes) |[mdaffin](https://github.com/mdaffin) |
-[](https://github.com/NickeZ) |[](https://github.com/nvzqz) |[](https://github.com/nuew) |[](https://github.com/Geogi) |[](https://github.com/flying-sheep) |[](https://github.com/Phlosioneer) |
+[](https://github.com/iliekturtles) |[](https://github.com/nicompte) |[](https://github.com/NickeZ) |[](https://github.com/nvzqz) |[](https://github.com/nuew) |[](https://github.com/Geogi) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[NickeZ](https://github.com/NickeZ) |[nvzqz](https://github.com/nvzqz) |[nuew](https://github.com/nuew) |[Geogi](https://github.com/Geogi) |[flying-sheep](https://github.com/flying-sheep) |[Phlosioneer](https://github.com/Phlosioneer) |
+[iliekturtles](https://github.com/iliekturtles) |[nicompte](https://github.com/nicompte) |[NickeZ](https://github.com/NickeZ) |[nvzqz](https://github.com/nvzqz) |[nuew](https://github.com/nuew) |[Geogi](https://github.com/Geogi) |
-[](https://github.com/peppsac) |[](https://github.com/golddranks) |[](https://github.com/hexjelly) |[](https://github.com/rnelson) |[](https://github.com/swatteau) |[](https://github.com/tspiteri) |
+[](https://github.com/focusaurus) |[](https://github.com/flying-sheep) |[](https://github.com/Phlosioneer) |[](https://github.com/peppsac) |[](https://github.com/golddranks) |[](https://github.com/hexjelly) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[peppsac](https://github.com/peppsac) |[golddranks](https://github.com/golddranks) |[hexjelly](https://github.com/hexjelly) |[rnelson](https://github.com/rnelson) |[swatteau](https://github.com/swatteau) |[tspiteri](https://github.com/tspiteri) |
+[focusaurus](https://github.com/focusaurus) |[flying-sheep](https://github.com/flying-sheep) |[Phlosioneer](https://github.com/Phlosioneer) |[peppsac](https://github.com/peppsac) |[golddranks](https://github.com/golddranks) |[hexjelly](https://github.com/hexjelly) |
-[](https://github.com/siiptuo) |[](https://github.com/vks) |[](https://github.com/vsupalov) |[](https://github.com/mineo) |[](https://github.com/wabain) |[](https://github.com/grossws) |
+[](https://github.com/rnelson) |[](https://github.com/swatteau) |[](https://github.com/tspiteri) |[](https://github.com/siiptuo) |[](https://github.com/vks) |[](https://github.com/vsupalov) |
:---: |:---: |:---: |:---: |:---: |:---: |
-[siiptuo](https://github.com/siiptuo) |[vks](https://github.com/vks) |[vsupalov](https://github.com/vsupalov) |[mineo](https://github.com/mineo) |[wabain](https://github.com/wabain) |[grossws](https://github.com/grossws) |
+[rnelson](https://github.com/rnelson) |[swatteau](https://github.com/swatteau) |[tspiteri](https://github.com/tspiteri) |[siiptuo](https://github.com/siiptuo) |[vks](https://github.com/vks) |[vsupalov](https://github.com/vsupalov) |
-[](https://github.com/kennytm) |[](https://github.com/mvaude) |[](https://github.com/panicbit) |[](https://github.com/mitsuhiko) |
-:---: |:---: |:---: |:---: |
-[kennytm](https://github.com/kennytm) |[mvaude](https://github.com/mvaude) |[panicbit](https://github.com/panicbit) |[mitsuhiko](https://github.com/mitsuhiko) |
+[](https://github.com/mineo) |[](https://github.com/wabain) |[](https://github.com/grossws) |[](https://github.com/kennytm) |[](https://github.com/mvaude) |[](https://github.com/panicbit) |
+:---: |:---: |:---: |:---: |:---: |:---: |
+[mineo](https://github.com/mineo) |[wabain](https://github.com/wabain) |[grossws](https://github.com/grossws) |[kennytm](https://github.com/kennytm) |[mvaude](https://github.com/mvaude) |[panicbit](https://github.com/panicbit) |
+
+[](https://github.com/mitsuhiko) |
+:---: |
+[mitsuhiko](https://github.com/mitsuhiko) |
diff --git a/README.md b/README.md
index dd7716df..c1e2c064 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,7 @@ The minimum required Rust is now 1.20. This was done to start using bitflags 1.0
* Updates `bitflags` to 1.0
* Adds the traits to be used with the `clap-derive` crate to be able to use Custom Derive (for now must be accessed with `unstable` feature flag)
+* Adds Arg::case_insensitive(bool) which allows matching Arg::possible_values without worrying about ASCII case
* Fixes a regression where --help couldn't be overridden
* adds '[SUBCOMMAND]' to usage strings with only AppSettings::AllowExternalSubcommands is used with no other subcommands
* uses `.bash` for Bash completion scripts now instead of `.bash-completion` due to convention and `.bash-completion` not being supported by completion projects
diff --git a/src/app/macros.rs b/src/app/macros.rs
index 099f326e..e3f15e96 100644
--- a/src/app/macros.rs
+++ b/src/app/macros.rs
@@ -85,7 +85,7 @@ macro_rules! arg_post_processing {
.filter(|&&(val, _)| val.is_none())
.filter(|&&(_, req)| !$matcher.contains(&req))
.map(|&(_, name)| name) {
-
+
$me.required.push(n);
}
} else { sdebugln!("No"); }
diff --git a/src/app/meta.rs b/src/app/meta.rs
index 6fbf412c..c7f128fe 100644
--- a/src/app/meta.rs
+++ b/src/app/meta.rs
@@ -23,5 +23,11 @@ pub struct AppMeta<'b> {
impl<'b> AppMeta<'b> {
pub fn new() -> Self { Default::default() }
- pub fn with_name(s: String) -> Self { AppMeta { name: s, disp_ord: 999, ..Default::default() } }
-}
\ No newline at end of file
+ pub fn with_name(s: String) -> Self {
+ AppMeta {
+ name: s,
+ disp_ord: 999,
+ ..Default::default()
+ }
+ }
+}
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 418be395..9c2d852b 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -60,10 +60,10 @@ use map::{self, VecMap};
/// [`App::get_matches`]: ./struct.App.html#method.get_matches
#[allow(missing_debug_implementations)]
pub struct App<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
- #[doc(hidden)]
- pub p: Parser<'a, 'b>,
+ #[doc(hidden)] pub p: Parser<'a, 'b>,
}
@@ -79,7 +79,11 @@ impl<'a, 'b> App<'a, 'b> {
/// let prog = App::new("My Program")
/// # ;
/// ```
- pub fn new>(n: S) -> Self { App { p: Parser::with_name(n.into()) } }
+ pub fn new>(n: S) -> Self {
+ App {
+ p: Parser::with_name(n.into()),
+ }
+ }
/// Get the name of the app
pub fn get_name(&self) -> &str { &self.p.meta.name }
@@ -103,7 +107,9 @@ impl<'a, 'b> App<'a, 'b> {
/// [`App::version`]: ./struct.App.html#method.author
#[deprecated(since="2.14.1", note="Can never work; use explicit App::author() and App::version() calls instead")]
pub fn with_defaults>(n: S) -> Self {
- let mut a = App { p: Parser::with_name(n.into()) };
+ let mut a = App {
+ p: Parser::with_name(n.into()),
+ };
a.p.meta.author = Some("Kevin K. ");
a.p.meta.version = Some("2.19.2");
a
@@ -1073,7 +1079,8 @@ impl<'a, 'b> App<'a, 'b> {
/// [`SubCommand`]: ./struct.SubCommand.html
/// [`IntoIterator`]: https://doc.rust-lang.org/std/iter/trait.IntoIterator.html
pub fn subcommands(mut self, subcmds: I) -> Self
- where I: IntoIterator- >
+ where
+ I: IntoIterator
- >,
{
for subcmd in subcmds {
self.p.add_subcommand(subcmd);
@@ -1380,10 +1387,12 @@ impl<'a, 'b> App<'a, 'b> {
/// `/target/debug/build/myapp-/out/myapp.bash`.
///
/// Fish shell completions will use the file format `{bin_name}.fish`
- pub fn gen_completions, S: Into>(&mut self,
- bin_name: S,
- for_shell: Shell,
- out_dir: T) {
+ pub fn gen_completions, S: Into>(
+ &mut self,
+ bin_name: S,
+ for_shell: Shell,
+ out_dir: T,
+ ) {
self.p.meta.bin_name = Some(bin_name.into());
self.p.gen_completions(for_shell, out_dir.into());
}
@@ -1421,10 +1430,12 @@ impl<'a, 'b> App<'a, 'b> {
/// ```shell
/// $ myapp generate-bash-completions > /usr/share/bash-completion/completions/myapp.bash
/// ```
- pub fn gen_completions_to>(&mut self,
- bin_name: S,
- for_shell: Shell,
- buf: &mut W) {
+ pub fn gen_completions_to>(
+ &mut self,
+ bin_name: S,
+ for_shell: Shell,
+ buf: &mut W,
+ ) {
self.p.meta.bin_name = Some(bin_name.into());
self.p.gen_completions_to(for_shell, buf);
}
@@ -1497,8 +1508,9 @@ impl<'a, 'b> App<'a, 'b> {
/// [`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html
/// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName
pub fn get_matches_from(mut self, itr: I) -> ArgMatches<'a>
- where I: IntoIterator
- ,
- T: Into + Clone
+ where
+ I: IntoIterator
- ,
+ T: Into + Clone,
{
self.get_matches_from_safe_borrow(itr).unwrap_or_else(|e| {
// Otherwise, write to stderr and exit
@@ -1553,8 +1565,9 @@ impl<'a, 'b> App<'a, 'b> {
/// [`kind`]: ./struct.Error.html
/// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName
pub fn get_matches_from_safe(mut self, itr: I) -> ClapResult>
- where I: IntoIterator
- ,
- T: Into + Clone
+ where
+ I: IntoIterator
- ,
+ T: Into + Clone,
{
self.get_matches_from_safe_borrow(itr)
}
@@ -1581,8 +1594,9 @@ impl<'a, 'b> App<'a, 'b> {
/// [`App::get_matches_from_safe`]: ./struct.App.html#method.get_matches_from_safe
/// [`AppSettings::NoBinaryName`]: ./enum.AppSettings.html#variant.NoBinaryName
pub fn get_matches_from_safe_borrow(&mut self, itr: I) -> ClapResult>
- where I: IntoIterator
- ,
- T: Into + Clone
+ where
+ I: IntoIterator
- ,
+ T: Into + Clone,
{
// If there are global arguments, or settings we need to propgate them down to subcommands
// before parsing incase we run into a subcommand
@@ -1622,7 +1636,7 @@ impl<'a, 'b> App<'a, 'b> {
return Err(e);
}
- let global_arg_vec : Vec<&str> = (&self).p.global_args.iter().map(|ga| ga.b.name).collect();
+ let global_arg_vec: Vec<&str> = (&self).p.global_args.iter().map(|ga| ga.b.name).collect();
matcher.propagate_globals(&global_arg_vec);
Ok(matcher.into())
@@ -1674,14 +1688,18 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> {
if let Some(v) = yaml["display_order"].as_i64() {
a = a.display_order(v as usize);
} else if yaml["display_order"] != Yaml::BadValue {
- panic!("Failed to convert YAML value {:?} to a u64",
- yaml["display_order"]);
+ panic!(
+ "Failed to convert YAML value {:?} to a u64",
+ yaml["display_order"]
+ );
}
if let Some(v) = yaml["setting"].as_str() {
a = a.setting(v.parse().expect("unknown AppSetting found in YAML file"));
} else if yaml["setting"] != Yaml::BadValue {
- panic!("Failed to convert YAML value {:?} to an AppSetting",
- yaml["setting"]);
+ panic!(
+ "Failed to convert YAML value {:?} to an AppSetting",
+ yaml["setting"]
+ );
}
if let Some(v) = yaml["settings"].as_vec() {
for ys in v {
@@ -1692,27 +1710,32 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> {
} else if let Some(v) = yaml["settings"].as_str() {
a = a.setting(v.parse().expect("unknown AppSetting found in YAML file"));
} else if yaml["settings"] != Yaml::BadValue {
- panic!("Failed to convert YAML value {:?} to a string",
- yaml["settings"]);
+ panic!(
+ "Failed to convert YAML value {:?} to a string",
+ yaml["settings"]
+ );
}
if let Some(v) = yaml["global_setting"].as_str() {
a = a.setting(v.parse().expect("unknown AppSetting found in YAML file"));
} else if yaml["global_setting"] != Yaml::BadValue {
- panic!("Failed to convert YAML value {:?} to an AppSetting",
- yaml["setting"]);
+ panic!(
+ "Failed to convert YAML value {:?} to an AppSetting",
+ yaml["setting"]
+ );
}
if let Some(v) = yaml["global_settings"].as_vec() {
for ys in v {
if let Some(s) = ys.as_str() {
- a = a.global_setting(s.parse()
- .expect("unknown AppSetting found in YAML file"));
+ a = a.global_setting(s.parse().expect("unknown AppSetting found in YAML file"));
}
}
} else if let Some(v) = yaml["global_settings"].as_str() {
a = a.global_setting(v.parse().expect("unknown AppSetting found in YAML file"));
} else if yaml["global_settings"] != Yaml::BadValue {
- panic!("Failed to convert YAML value {:?} to a string",
- yaml["global_settings"]);
+ panic!(
+ "Failed to convert YAML value {:?} to a string",
+ yaml["global_settings"]
+ );
}
macro_rules! vec_or_str {
@@ -1800,8 +1823,10 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
fn longest_filter(&self) -> bool { true }
fn aliases(&self) -> Option> {
if let Some(ref aliases) = self.p.meta.aliases {
- let vis_aliases: Vec<_> =
- aliases.iter().filter_map(|&(n, v)| if v { Some(n) } else { None }).collect();
+ let vis_aliases: Vec<_> = aliases
+ .iter()
+ .filter_map(|&(n, v)| if v { Some(n) } else { None })
+ .collect();
if vis_aliases.is_empty() {
None
} else {
diff --git a/src/app/parser.rs b/src/app/parser.rs
index 8cd49097..22c45c9a 100644
--- a/src/app/parser.rs
+++ b/src/app/parser.rs
@@ -17,7 +17,7 @@ use app::App;
use app::help::Help;
use app::meta::AppMeta;
use app::settings::AppFlags;
-use args::{AnyArg, ArgMatcher, Base, Switched, Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder};
+use args::{AnyArg, Arg, ArgGroup, ArgMatcher, Base, FlagBuilder, OptBuilder, PosBuilder, Switched};
use args::settings::ArgSettings;
use completions::ComplGen;
use errors::{Error, ErrorKind};
@@ -47,7 +47,8 @@ pub enum ParseResult<'a> {
#[doc(hidden)]
#[derive(Clone, Default)]
pub struct Parser<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
pub meta: AppMeta<'b>,
settings: AppFlags,
@@ -70,7 +71,8 @@ pub struct Parser<'a, 'b>
}
impl<'a, 'b> Parser<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
pub fn with_name(n: String) -> Self {
Parser {
@@ -130,79 +132,85 @@ impl<'a, 'b> Parser<'a, 'b>
#[inline]
fn app_debug_asserts(&mut self) -> bool {
assert!(self.verify_positionals());
- let should_err = self.groups
- .iter()
- .all(|g| {
- g.args
- .iter()
- .all(|arg| {
- (self.flags.iter().any(|f| &f.b.name == arg) ||
- self.opts.iter().any(|o| &o.b.name == arg) ||
- self.positionals.values().any(|p| &p.b.name == arg) ||
- self.groups.iter().any(|g| &g.name == arg))
- })
- });
- let g = self.groups
- .iter()
- .find(|g| {
- g.args
- .iter()
- .any(|arg| {
- !(self.flags.iter().any(|f| &f.b.name == arg) ||
- self.opts.iter().any(|o| &o.b.name == arg) ||
- self.positionals.values().any(|p| &p.b.name == arg) ||
- self.groups.iter().any(|g| &g.name == arg))
- })
- });
- assert!(should_err,
- "The group '{}' contains the arg '{}' that doesn't actually exist.",
- g.unwrap().name,
- g.unwrap()
- .args
- .iter()
- .find(|arg| {
- !(self.flags.iter().any(|f| &&f.b.name == arg) ||
- self.opts.iter().any(|o| &&o.b.name == arg) ||
- self.positionals.values().any(|p| &&p.b.name == arg) ||
- self.groups.iter().any(|g| &&g.name == arg))
- })
- .unwrap());
+ let should_err = self.groups.iter().all(|g| {
+ g.args.iter().all(|arg| {
+ (self.flags.iter().any(|f| &f.b.name == arg)
+ || self.opts.iter().any(|o| &o.b.name == arg)
+ || self.positionals.values().any(|p| &p.b.name == arg)
+ || self.groups.iter().any(|g| &g.name == arg))
+ })
+ });
+ let g = self.groups.iter().find(|g| {
+ g.args.iter().any(|arg| {
+ !(self.flags.iter().any(|f| &f.b.name == arg)
+ || self.opts.iter().any(|o| &o.b.name == arg)
+ || self.positionals.values().any(|p| &p.b.name == arg)
+ || self.groups.iter().any(|g| &g.name == arg))
+ })
+ });
+ assert!(
+ should_err,
+ "The group '{}' contains the arg '{}' that doesn't actually exist.",
+ g.unwrap().name,
+ g.unwrap()
+ .args
+ .iter()
+ .find(|arg| {
+ !(self.flags.iter().any(|f| &&f.b.name == arg)
+ || self.opts.iter().any(|o| &&o.b.name == arg)
+ || self.positionals.values().any(|p| &&p.b.name == arg)
+ || self.groups.iter().any(|g| &&g.name == arg))
+ })
+ .unwrap()
+ );
true
}
#[inline]
fn debug_asserts(&self, a: &Arg) -> bool {
- assert!(!arg_names!(self).any(|name| name == a.b.name),
- format!("Non-unique argument name: {} is already in use", a.b.name));
+ assert!(
+ !arg_names!(self).any(|name| name == a.b.name),
+ format!("Non-unique argument name: {} is already in use", a.b.name)
+ );
if let Some(l) = a.s.long {
- assert!(!self.contains_long(l),
- "Argument long must be unique\n\n\t--{} is already in use",
- l);
+ assert!(
+ !self.contains_long(l),
+ "Argument long must be unique\n\n\t--{} is already in use",
+ l
+ );
}
if let Some(s) = a.s.short {
- assert!(!self.contains_short(s),
- "Argument short must be unique\n\n\t-{} is already in use",
- s);
+ assert!(
+ !self.contains_short(s),
+ "Argument short must be unique\n\n\t-{} is already in use",
+ s
+ );
}
let i = if a.index.is_none() {
(self.positionals.len() + 1)
} else {
a.index.unwrap() as usize
};
- assert!(!self.positionals.contains_key(i),
- "Argument \"{}\" has the same index as another positional \
- argument\n\n\tPerhaps try .multiple(true) to allow one positional argument \
- to take multiple values",
- a.b.name);
- assert!(!(a.is_set(ArgSettings::Required) && a.is_set(ArgSettings::Global)),
- "Global arguments cannot be required.\n\n\t'{}' is marked as \
- global and required",
- a.b.name);
+ assert!(
+ !self.positionals.contains_key(i),
+ "Argument \"{}\" has the same index as another positional \
+ argument\n\n\tPerhaps try .multiple(true) to allow one positional argument \
+ to take multiple values",
+ a.b.name
+ );
+ assert!(
+ !(a.is_set(ArgSettings::Required) && a.is_set(ArgSettings::Global)),
+ "Global arguments cannot be required.\n\n\t'{}' is marked as \
+ global and required",
+ a.b.name
+ );
if a.b.is_set(ArgSettings::Last) {
- assert!(!self.positionals
- .values()
- .any(|p| p.b.is_set(ArgSettings::Last)),
- "Only one positional argument may have last(true) set. Found two.");
+ assert!(
+ !self.positionals
+ .values()
+ .any(|p| p.b.is_set(ArgSettings::Last)),
+ "Only one positional argument may have last(true) set. Found two."
+ );
assert!(a.s.long.is_none(),
"Flags or Options may not have last(true) set. {} has both a long and last(true) set.",
a.b.name);
@@ -246,9 +254,10 @@ impl<'a, 'b> Parser<'a, 'b>
// If the arg is required, add all it's requirements to master required list
if let Some(ref areqs) = a.b.requires {
for name in areqs
- .iter()
- .filter(|&&(val, _)| val.is_none())
- .map(|&(_, name)| name) {
+ .iter()
+ .filter(|&&(val, _)| val.is_none())
+ .map(|&(_, name)| name)
+ {
self.required.push(name);
}
}
@@ -356,9 +365,11 @@ impl<'a, 'b> Parser<'a, 'b>
}
pub fn add_subcommand(&mut self, mut subcmd: App<'a, 'b>) {
- debugln!("Parser::add_subcommand: term_w={:?}, name={}",
- self.meta.term_w,
- subcmd.p.meta.name);
+ debugln!(
+ "Parser::add_subcommand: term_w={:?}, name={}",
+ self.meta.term_w,
+ subcmd.p.meta.name
+ );
subcmd.p.meta.term_w = self.meta.term_w;
if subcmd.p.meta.name == "help" {
self.unset(AS::NeedsSubcommandHelp);
@@ -368,14 +379,18 @@ impl<'a, 'b> Parser<'a, 'b>
}
pub fn propagate_settings(&mut self) {
- debugln!("Parser::propagate_settings: self={}, g_settings={:#?}",
- self.meta.name,
- self.g_settings);
+ debugln!(
+ "Parser::propagate_settings: self={}, g_settings={:#?}",
+ self.meta.name,
+ self.g_settings
+ );
for sc in &mut self.subcommands {
- debugln!("Parser::propagate_settings: sc={}, settings={:#?}, g_settings={:#?}",
- sc.p.meta.name,
- sc.p.settings,
- sc.p.g_settings);
+ debugln!(
+ "Parser::propagate_settings: sc={}, settings={:#?}, g_settings={:#?}",
+ sc.p.meta.name,
+ sc.p.settings,
+ sc.p.g_settings
+ );
// We have to create a new scope in order to tell rustc the borrow of `sc` is
// done and to recursively call this method
{
@@ -403,21 +418,24 @@ impl<'a, 'b> Parser<'a, 'b>
if self.is_set(AS::DeriveDisplayOrder) {
let unified = self.is_set(AS::UnifiedHelpMessage);
for (i, o) in self.opts
- .iter_mut()
- .enumerate()
- .filter(|&(_, ref o)| o.s.disp_ord == 999) {
+ .iter_mut()
+ .enumerate()
+ .filter(|&(_, ref o)| o.s.disp_ord == 999)
+ {
o.s.disp_ord = if unified { o.s.unified_ord } else { i };
}
for (i, f) in self.flags
- .iter_mut()
- .enumerate()
- .filter(|&(_, ref f)| f.s.disp_ord == 999) {
+ .iter_mut()
+ .enumerate()
+ .filter(|&(_, ref f)| f.s.disp_ord == 999)
+ {
f.s.disp_ord = if unified { f.s.unified_ord } else { i };
}
for (i, sc) in &mut self.subcommands
- .iter_mut()
- .enumerate()
- .filter(|&(_, ref sc)| sc.p.meta.disp_ord == 999) {
+ .iter_mut()
+ .enumerate()
+ .filter(|&(_, ref sc)| sc.p.meta.disp_ord == 999)
+ {
sc.p.meta.disp_ord = i;
}
}
@@ -474,7 +492,11 @@ impl<'a, 'b> Parser<'a, 'b>
#[inline]
pub fn has_visible_subcommands(&self) -> bool {
- self.has_subcommands() && self.subcommands.iter().filter(|sc| sc.p.meta.name != "help").any(|sc| !sc.p.is_set(AS::Hidden))
+ self.has_subcommands()
+ && self.subcommands
+ .iter()
+ .filter(|sc| sc.p.meta.name != "help")
+ .any(|sc| !sc.p.is_set(AS::Hidden))
}
#[inline]
@@ -495,50 +517,57 @@ impl<'a, 'b> Parser<'a, 'b>
// positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3
// but no 2)
if let Some((idx, p)) = self.positionals.iter().rev().next() {
- assert!(!(idx != self.positionals.len()),
- "Found positional argument \"{}\" whose index is {} but there \
- are only {} positional arguments defined",
- p.b.name,
- idx,
- self.positionals.len());
+ assert!(
+ !(idx != self.positionals.len()),
+ "Found positional argument \"{}\" whose index is {} but there \
+ are only {} positional arguments defined",
+ p.b.name,
+ idx,
+ self.positionals.len()
+ );
}
// Next we verify that only the highest index has a .multiple(true) (if any)
- if self.positionals
- .values()
- .any(|a| {
- a.b.is_set(ArgSettings::Multiple) &&
- (a.index as usize != self.positionals.len())
- }) {
+ if self.positionals.values().any(|a| {
+ a.b.is_set(ArgSettings::Multiple) && (a.index as usize != self.positionals.len())
+ }) {
let mut it = self.positionals.values().rev();
let last = it.next().unwrap();
let second_to_last = it.next().unwrap();
// Either the final positional is required
// Or the second to last has a terminator or .last(true) set
- let ok = last.is_set(ArgSettings::Required) ||
- (second_to_last.v.terminator.is_some() ||
- second_to_last.b.is_set(ArgSettings::Last)) ||
- last.is_set(ArgSettings::Last);
- assert!(ok,
- "When using a positional argument with .multiple(true) that is *not the \
- last* positional argument, the last positional argument (i.e the one \
- with the highest index) *must* have .required(true) or .last(true) set.");
+ let ok = last.is_set(ArgSettings::Required)
+ || (second_to_last.v.terminator.is_some()
+ || second_to_last.b.is_set(ArgSettings::Last))
+ || last.is_set(ArgSettings::Last);
+ assert!(
+ ok,
+ "When using a positional argument with .multiple(true) that is *not the \
+ last* positional argument, the last positional argument (i.e the one \
+ with the highest index) *must* have .required(true) or .last(true) set."
+ );
let ok = second_to_last.is_set(ArgSettings::Multiple) || last.is_set(ArgSettings::Last);
- assert!(ok,
- "Only the last positional argument, or second to last positional \
- argument may be set to .multiple(true)");
+ assert!(
+ ok,
+ "Only the last positional argument, or second to last positional \
+ argument may be set to .multiple(true)"
+ );
let count = self.positionals
.values()
- .filter(|p| p.b.settings.is_set(ArgSettings::Multiple) && p.v.num_vals.is_none())
+ .filter(|p| {
+ p.b.settings.is_set(ArgSettings::Multiple) && p.v.num_vals.is_none()
+ })
.count();
- let ok = count <= 1 ||
- (last.is_set(ArgSettings::Last) && last.is_set(ArgSettings::Multiple) &&
- second_to_last.is_set(ArgSettings::Multiple) &&
- count == 2);
- assert!(ok,
- "Only one positional argument with .multiple(true) set is allowed per \
- command, unless the second one also has .last(true) set");
+ let ok = count <= 1
+ || (last.is_set(ArgSettings::Last) && last.is_set(ArgSettings::Multiple)
+ && second_to_last.is_set(ArgSettings::Multiple)
+ && count == 2);
+ assert!(
+ ok,
+ "Only one positional argument with .multiple(true) set is allowed per \
+ command, unless the second one also has .last(true) set"
+ );
}
@@ -549,12 +578,14 @@ impl<'a, 'b> Parser<'a, 'b>
let mut foundx2 = false;
for p in self.positionals.values().rev() {
if foundx2 && !p.b.settings.is_set(ArgSettings::Required) {
- assert!(p.b.is_set(ArgSettings::Required),
- "Found positional argument which is not required with a lower \
- index than a required positional argument by two or more: {:?} \
- index {}",
- p.b.name,
- p.index);
+ assert!(
+ p.b.is_set(ArgSettings::Required),
+ "Found positional argument which is not required with a lower \
+ index than a required positional argument by two or more: {:?} \
+ index {}",
+ p.b.name,
+ p.index
+ );
} else if p.b.is_set(ArgSettings::Required) && !p.b.is_set(ArgSettings::Last) {
// Args that .last(true) don't count since they can be required and have
// positionals with a lower index that aren't required
@@ -578,11 +609,13 @@ impl<'a, 'b> Parser<'a, 'b>
let mut found = false;
for p in self.positionals.values().rev() {
if found {
- assert!(p.b.is_set(ArgSettings::Required),
- "Found positional argument which is not required with a lower \
- index than a required positional argument: {:?} index {}",
- p.b.name,
- p.index);
+ assert!(
+ p.b.is_set(ArgSettings::Required),
+ "Found positional argument which is not required with a lower \
+ index than a required positional argument: {:?} index {}",
+ p.b.name,
+ p.index
+ );
} else if p.b.is_set(ArgSettings::Required) && !p.b.is_set(ArgSettings::Last) {
// Args that .last(true) don't count since they can be required and have
// positionals with a lower index that aren't required
@@ -595,14 +628,14 @@ impl<'a, 'b> Parser<'a, 'b>
}
}
}
- if self.positionals
- .values()
- .any(|p| {
- p.b.is_set(ArgSettings::Last) && p.b.is_set(ArgSettings::Required)
- }) && self.has_subcommands() &&
- !self.is_set(AS::SubcommandsNegateReqs) {
- panic!("Having a required positional argument with .last(true) set *and* child \
- subcommands without setting SubcommandsNegateReqs isn't compatible.");
+ if self.positionals.values().any(|p| {
+ p.b.is_set(ArgSettings::Last) && p.b.is_set(ArgSettings::Required)
+ }) && self.has_subcommands() && !self.is_set(AS::SubcommandsNegateReqs)
+ {
+ panic!(
+ "Having a required positional argument with .last(true) set *and* child \
+ subcommands without setting SubcommandsNegateReqs isn't compatible."
+ );
}
true
@@ -647,16 +680,16 @@ impl<'a, 'b> Parser<'a, 'b>
let v = self.subcommands
.iter()
.filter(|s| {
- starts(&s.p.meta.name[..], &*arg_os) ||
- (s.p.meta.aliases.is_some() &&
- s.p
- .meta
- .aliases
- .as_ref()
- .unwrap()
- .iter()
- .filter(|&&(a, _)| starts(a, &*arg_os))
- .count() == 1)
+ starts(&s.p.meta.name[..], &*arg_os)
+ || (s.p.meta.aliases.is_some()
+ && s.p
+ .meta
+ .aliases
+ .as_ref()
+ .unwrap()
+ .iter()
+ .filter(|&&(a, _)| starts(a, &*arg_os))
+ .count() == 1)
})
.map(|sc| &sc.p.meta.name)
.collect::>();
@@ -669,8 +702,9 @@ impl<'a, 'b> Parser<'a, 'b>
}
fn parse_help_subcommand(&self, it: &mut I) -> ClapResult>
- where I: Iterator
- ,
- T: Into
+ where
+ I: Iterator
- ,
+ T: Into,
{
debugln!("Parser::parse_help_subcommand;");
let cmds: Vec = it.map(|c| c.into()).collect();
@@ -688,32 +722,35 @@ impl<'a, 'b> Parser<'a, 'b>
help_help = true;
}
if let Some(c) = sc.subcommands
- .iter()
- .find(|s| &*s.p.meta.name == cmd)
- .map(|sc| &sc.p) {
+ .iter()
+ .find(|s| &*s.p.meta.name == cmd)
+ .map(|sc| &sc.p)
+ {
sc = c;
if i == cmds.len() - 1 {
break;
}
} else if let Some(c) = sc.subcommands
- .iter()
- .find(|s| if let Some(ref als) = s.p.meta.aliases {
- als.iter().any(|&(a, _)| a == &*cmd.to_string_lossy())
- } else {
- false
- })
- .map(|sc| &sc.p) {
+ .iter()
+ .find(|s| {
+ if let Some(ref als) = s.p.meta.aliases {
+ als.iter().any(|&(a, _)| a == &*cmd.to_string_lossy())
+ } else {
+ false
+ }
+ })
+ .map(|sc| &sc.p)
+ {
sc = c;
if i == cmds.len() - 1 {
break;
}
} else {
- return Err(Error::unrecognized_subcommand(cmd.to_string_lossy().into_owned(),
- self.meta
- .bin_name
- .as_ref()
- .unwrap_or(&self.meta.name),
- self.color()));
+ return Err(Error::unrecognized_subcommand(
+ cmd.to_string_lossy().into_owned(),
+ self.meta.bin_name.as_ref().unwrap_or(&self.meta.name),
+ self.color(),
+ ));
}
bin_name = format!("{} {}", bin_name, &*sc.meta.name);
}
@@ -737,9 +774,11 @@ impl<'a, 'b> Parser<'a, 'b>
// allow wrong self convention due to self.valid_neg_num = true and it's a private method
#[cfg_attr(feature = "lints", allow(wrong_self_convention))]
fn is_new_arg(&mut self, arg_os: &OsStr, needs_val_of: ParseResult<'a>) -> bool {
- debugln!("Parser::is_new_arg: arg={:?}, Needs Val of={:?}",
- arg_os,
- needs_val_of);
+ debugln!(
+ "Parser::is_new_arg: arg={:?}, Needs Val of={:?}",
+ arg_os,
+ needs_val_of
+ );
let app_wide_settings = if self.is_set(AS::AllowLeadingHyphen) {
true
} else if self.is_set(AS::AllowNegativeNumbers) {
@@ -770,8 +809,10 @@ impl<'a, 'b> Parser<'a, 'b>
}
_ => false,
};
- debugln!("Parser::is_new_arg: Arg::allow_leading_hyphen({:?})",
- arg_allows_tac);
+ debugln!(
+ "Parser::is_new_arg: Arg::allow_leading_hyphen({:?})",
+ arg_allows_tac
+ );
// Is this a new argument, or values from a previous option?
let mut ret = if arg_os.starts_with(b"--") {
@@ -799,26 +840,26 @@ impl<'a, 'b> Parser<'a, 'b>
// The actual parsing function
#[cfg_attr(feature = "lints", allow(while_let_on_iterator, collapsible_if))]
- pub fn get_matches_with(&mut self,
- matcher: &mut ArgMatcher<'a>,
- it: &mut Peekable)
- -> ClapResult<()>
- where I: Iterator
- ,
- T: Into + Clone
+ pub fn get_matches_with(
+ &mut self,
+ matcher: &mut ArgMatcher<'a>,
+ it: &mut Peekable,
+ ) -> ClapResult<()>
+ where
+ I: Iterator
- ,
+ T: Into + Clone,
{
debugln!("Parser::get_matches_with;");
// Verify all positional assertions pass
debug_assert!(self.app_debug_asserts());
- if self.positionals
- .values()
- .any(|a| {
- a.b.is_set(ArgSettings::Multiple) &&
- (a.index as usize != self.positionals.len())
- }) &&
- self.positionals
- .values()
- .last()
- .map_or(false, |p| !p.is_set(ArgSettings::Last)) {
+ if self.positionals.values().any(|a| {
+ a.b.is_set(ArgSettings::Multiple) && (a.index as usize != self.positionals.len())
+ })
+ && self.positionals
+ .values()
+ .last()
+ .map_or(false, |p| !p.is_set(ArgSettings::Last))
+ {
self.settings.set(AS::LowIndexMultiplePositional);
}
let has_args = self.has_args();
@@ -832,9 +873,11 @@ impl<'a, 'b> Parser<'a, 'b>
let mut pos_counter = 1;
while let Some(arg) = it.next() {
let arg_os = arg.into();
- debugln!("Parser::get_matches_with: Begin parsing '{:?}' ({:?})",
- arg_os,
- &*arg_os.as_bytes());
+ debugln!(
+ "Parser::get_matches_with: Begin parsing '{:?}' ({:?})",
+ arg_os,
+ &*arg_os.as_bytes()
+ );
self.unset(AS::ValidNegNumFound);
// Is this a new argument, or values from a previous option?
@@ -850,12 +893,14 @@ impl<'a, 'b> Parser<'a, 'b>
// Does the arg match a subcommand name, or any of it's aliases (if defined)
{
match needs_val_of {
- ParseResult::Opt(_) | ParseResult::Pos(_) =>(),
+ ParseResult::Opt(_) | ParseResult::Pos(_) => (),
_ => {
let (is_match, sc_name) = self.possible_subcommand(&arg_os);
- debugln!("Parser::get_matches_with: possible_sc={:?}, sc={:?}",
- is_match,
- sc_name);
+ debugln!(
+ "Parser::get_matches_with: possible_sc={:?}, sc={:?}",
+ is_match,
+ sc_name
+ );
if is_match {
let sc_name = sc_name.expect(INTERNAL_ERROR_MSG);
if sc_name == "help" && self.is_set(AS::NeedsSubcommandHelp) {
@@ -870,24 +915,26 @@ impl<'a, 'b> Parser<'a, 'b>
if !starts_new_arg {
if let ParseResult::Opt(name) = needs_val_of {
- // Check to see if parsing a value from a previous arg
- let arg = self.opts
- .iter()
- .find(|o| o.b.name == name)
- .expect(INTERNAL_ERROR_MSG);
- // get the OptBuilder so we can check the settings
- needs_val_of = self.add_val_to_arg(arg, &arg_os, matcher)?;
- // get the next value from the iterator
- continue;
+ // Check to see if parsing a value from a previous arg
+ let arg = self.opts
+ .iter()
+ .find(|o| o.b.name == name)
+ .expect(INTERNAL_ERROR_MSG);
+ // get the OptBuilder so we can check the settings
+ needs_val_of = self.add_val_to_arg(arg, &arg_os, matcher)?;
+ // get the next value from the iterator
+ continue;
}
} else if arg_os.starts_with(b"--") {
needs_val_of = self.parse_long_arg(matcher, &arg_os)?;
- debugln!("Parser:get_matches_with: After parse_long_arg {:?}",
- needs_val_of);
+ debugln!(
+ "Parser:get_matches_with: After parse_long_arg {:?}",
+ needs_val_of
+ );
match needs_val_of {
- ParseResult::Flag |
- ParseResult::Opt(..) |
- ParseResult::ValuesDone => continue,
+ ParseResult::Flag | ParseResult::Opt(..) | ParseResult::ValuesDone => {
+ continue
+ }
_ => (),
}
} else if arg_os.starts_with(b"-") && arg_os.len_() != 1 {
@@ -896,53 +943,59 @@ impl<'a, 'b> Parser<'a, 'b>
// an error, and instead return Ok(None)
needs_val_of = self.parse_short_arg(matcher, &arg_os)?;
// If it's None, we then check if one of those two AppSettings was set
- debugln!("Parser:get_matches_with: After parse_short_arg {:?}",
- needs_val_of);
+ debugln!(
+ "Parser:get_matches_with: After parse_short_arg {:?}",
+ needs_val_of
+ );
match needs_val_of {
ParseResult::MaybeNegNum => {
- if !(arg_os.to_string_lossy().parse::().is_ok() ||
- arg_os.to_string_lossy().parse::().is_ok()) {
- return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
- "",
- &*usage::create_error_usage(self, matcher, None),
- self.color()));
+ if !(arg_os.to_string_lossy().parse::().is_ok()
+ || arg_os.to_string_lossy().parse::().is_ok())
+ {
+ return Err(Error::unknown_argument(
+ &*arg_os.to_string_lossy(),
+ "",
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
}
- ParseResult::Opt(..) |
- ParseResult::Flag |
- ParseResult::ValuesDone => continue,
+ ParseResult::Opt(..) | ParseResult::Flag | ParseResult::ValuesDone => {
+ continue
+ }
_ => (),
}
}
- if !(self.is_set(AS::ArgsNegateSubcommands) && self.is_set(AS::ValidArgFound)) &&
- !self.is_set(AS::InferSubcommands) {
- if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(),
- sc_names!(self)) {
- return Err(Error::invalid_subcommand(arg_os
- .to_string_lossy()
- .into_owned(),
- cdate,
- self.meta
- .bin_name
- .as_ref()
- .unwrap_or(&self.meta.name),
- &*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ if !(self.is_set(AS::ArgsNegateSubcommands) && self.is_set(AS::ValidArgFound))
+ && !self.is_set(AS::InferSubcommands)
+ {
+ if let Some(cdate) =
+ suggestions::did_you_mean(&*arg_os.to_string_lossy(), sc_names!(self))
+ {
+ return Err(Error::invalid_subcommand(
+ arg_os.to_string_lossy().into_owned(),
+ cdate,
+ self.meta.bin_name.as_ref().unwrap_or(&self.meta.name),
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
}
}
- let low_index_mults = self.is_set(AS::LowIndexMultiplePositional) &&
- pos_counter == (self.positionals.len() - 1);
- let missing_pos = self.is_set(AS::AllowMissingPositional) &&
- pos_counter == (self.positionals.len() - 1);
- debugln!("Parser::get_matches_with: Positional counter...{}",
- pos_counter);
- debugln!("Parser::get_matches_with: Low index multiples...{:?}",
- low_index_mults);
+ let low_index_mults = self.is_set(AS::LowIndexMultiplePositional)
+ && pos_counter == (self.positionals.len() - 1);
+ let missing_pos = self.is_set(AS::AllowMissingPositional)
+ && pos_counter == (self.positionals.len() - 1);
+ debugln!(
+ "Parser::get_matches_with: Positional counter...{}",
+ pos_counter
+ );
+ debugln!(
+ "Parser::get_matches_with: Low index multiples...{:?}",
+ low_index_mults
+ );
if low_index_mults || missing_pos {
if let Some(na) = it.peek() {
let n = (*na).clone().into();
@@ -955,11 +1008,11 @@ impl<'a, 'b> Parser<'a, 'b>
} else {
ParseResult::ValuesDone
};
- let sc_match = {
- self.possible_subcommand(&n).0
- };
- if self.is_new_arg(&n, needs_val_of) || sc_match ||
- suggestions::did_you_mean(&n.to_string_lossy(), sc_names!(self)).is_some() {
+ let sc_match = { self.possible_subcommand(&n).0 };
+ if self.is_new_arg(&n, needs_val_of) || sc_match
+ || suggestions::did_you_mean(&n.to_string_lossy(), sc_names!(self))
+ .is_some()
+ {
debugln!("Parser::get_matches_with: Bumping the positional counter...");
pos_counter += 1;
}
@@ -975,12 +1028,12 @@ impl<'a, 'b> Parser<'a, 'b>
}
if let Some(p) = self.positionals.get(pos_counter) {
if p.is_set(ArgSettings::Last) && !self.is_set(AS::TrailingValues) {
- return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
- "",
- &*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ return Err(Error::unknown_argument(
+ &*arg_os.to_string_lossy(),
+ "",
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
parse_positional!(self, p, arg_os, pos_counter, matcher);
self.settings.set(AS::ValidArgFound);
@@ -990,10 +1043,10 @@ impl<'a, 'b> Parser<'a, 'b>
Some(s) => s.to_string(),
None => {
if !self.is_set(AS::StrictUtf8) {
- return Err(Error::invalid_utf8(&*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ return Err(Error::invalid_utf8(
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
arg_os.to_string_lossy().into_owned()
}
@@ -1004,57 +1057,54 @@ impl<'a, 'b> Parser<'a, 'b>
while let Some(v) = it.next() {
let a = v.into();
if a.to_str().is_none() && !self.is_set(AS::StrictUtf8) {
- return Err(Error::invalid_utf8(&*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ return Err(Error::invalid_utf8(
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
sc_m.add_val_to("", &a);
}
matcher.subcommand(SubCommand {
- name: sc_name,
- matches: sc_m.into(),
- });
- } else if !((self.is_set(AS::AllowLeadingHyphen) ||
- self.is_set(AS::AllowNegativeNumbers)) && arg_os.starts_with(b"-")) &&
- !self.is_set(AS::InferSubcommands) {
- return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
- "",
- &*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ name: sc_name,
+ matches: sc_m.into(),
+ });
+ } else if !((self.is_set(AS::AllowLeadingHyphen)
+ || self.is_set(AS::AllowNegativeNumbers))
+ && arg_os.starts_with(b"-"))
+ && !self.is_set(AS::InferSubcommands)
+ {
+ return Err(Error::unknown_argument(
+ &*arg_os.to_string_lossy(),
+ "",
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
} else if !has_args || self.is_set(AS::InferSubcommands) && self.has_subcommands() {
- if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(),
- sc_names!(self)) {
- return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(),
- cdate,
- self.meta
- .bin_name
- .as_ref()
- .unwrap_or(&self.meta.name),
- &*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ if let Some(cdate) =
+ suggestions::did_you_mean(&*arg_os.to_string_lossy(), sc_names!(self))
+ {
+ return Err(Error::invalid_subcommand(
+ arg_os.to_string_lossy().into_owned(),
+ cdate,
+ self.meta.bin_name.as_ref().unwrap_or(&self.meta.name),
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
} else {
- return Err(Error::unrecognized_subcommand(arg_os
- .to_string_lossy()
- .into_owned(),
- self.meta
- .bin_name
- .as_ref()
- .unwrap_or(&self.meta.name),
- self.color()));
+ return Err(Error::unrecognized_subcommand(
+ arg_os.to_string_lossy().into_owned(),
+ self.meta.bin_name.as_ref().unwrap_or(&self.meta.name),
+ self.color(),
+ ));
}
} else {
- return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
- "",
- &*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ return Err(Error::unknown_argument(
+ &*arg_os.to_string_lossy(),
+ "",
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
}
@@ -1070,18 +1120,20 @@ impl<'a, 'b> Parser<'a, 'b>
self.parse_subcommand(&*sc_name, matcher, it)?;
} else if self.is_set(AS::SubcommandRequired) {
let bn = self.meta.bin_name.as_ref().unwrap_or(&self.meta.name);
- return Err(Error::missing_subcommand(bn,
- &usage::create_error_usage(self, matcher, None),
- self.color()));
+ return Err(Error::missing_subcommand(
+ bn,
+ &usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
} else if self.is_set(AS::SubcommandRequiredElseHelp) {
debugln!("Parser::get_matches_with: SubcommandRequiredElseHelp=true");
let mut out = vec![];
self.write_help_err(&mut out)?;
return Err(Error {
- message: String::from_utf8_lossy(&*out).into_owned(),
- kind: ErrorKind::MissingArgumentOrSubcommand,
- info: None,
- });
+ message: String::from_utf8_lossy(&*out).into_owned(),
+ kind: ErrorKind::MissingArgumentOrSubcommand,
+ info: None,
+ });
}
Validator::new(self).validate(needs_val_of, subcmd_name, matcher)
@@ -1102,37 +1154,45 @@ impl<'a, 'b> Parser<'a, 'b>
debug!("Parser::build_bin_names:iter: bin_name set...");
if sc.p.meta.bin_name.is_none() {
sdebugln!("No");
- let bin_name = format!("{}{}{}",
- self.meta
- .bin_name
- .as_ref()
- .unwrap_or(&self.meta.name.clone()),
- if self.meta.bin_name.is_some() {
- " "
- } else {
- ""
- },
- &*sc.p.meta.name);
- debugln!("Parser::build_bin_names:iter: Setting bin_name of {} to {}",
- self.meta.name,
- bin_name);
+ let bin_name = format!(
+ "{}{}{}",
+ self.meta
+ .bin_name
+ .as_ref()
+ .unwrap_or(&self.meta.name.clone()),
+ if self.meta.bin_name.is_some() {
+ " "
+ } else {
+ ""
+ },
+ &*sc.p.meta.name
+ );
+ debugln!(
+ "Parser::build_bin_names:iter: Setting bin_name of {} to {}",
+ self.meta.name,
+ bin_name
+ );
sc.p.meta.bin_name = Some(bin_name);
} else {
sdebugln!("yes ({:?})", sc.p.meta.bin_name);
}
- debugln!("Parser::build_bin_names:iter: Calling build_bin_names from...{}",
- sc.p.meta.name);
+ debugln!(
+ "Parser::build_bin_names:iter: Calling build_bin_names from...{}",
+ sc.p.meta.name
+ );
sc.p.build_bin_names();
}
}
- fn parse_subcommand(&mut self,
- sc_name: &str,
- matcher: &mut ArgMatcher<'a>,
- it: &mut Peekable)
- -> ClapResult<()>
- where I: Iterator
- ,
- T: Into + Clone
+ fn parse_subcommand(
+ &mut self,
+ sc_name: &str,
+ matcher: &mut ArgMatcher<'a>,
+ it: &mut Peekable,
+ ) -> ClapResult<()>
+ where
+ I: Iterator
- ,
+ T: Into + Clone,
{
use std::fmt::Write;
debugln!("Parser::parse_subcommand;");
@@ -1150,36 +1210,42 @@ impl<'a, 'b> Parser<'a, 'b>
}
mid_string.push_str(" ");
if let Some(ref mut sc) = self.subcommands
- .iter_mut()
- .find(|s| s.p.meta.name == sc_name) {
+ .iter_mut()
+ .find(|s| s.p.meta.name == sc_name)
+ {
let mut sc_matcher = ArgMatcher::new();
// bin_name should be parent's bin_name + [] + the sc's name separated by
// a space
- sc.p.meta.usage = Some(format!("{}{}{}",
- self.meta.bin_name.as_ref().unwrap_or(&String::new()),
- if self.meta.bin_name.is_some() {
- &*mid_string
- } else {
- ""
- },
- &*sc.p.meta.name));
- sc.p.meta.bin_name =
- Some(format!("{}{}{}",
- self.meta.bin_name.as_ref().unwrap_or(&String::new()),
- if self.meta.bin_name.is_some() {
- " "
- } else {
- ""
- },
- &*sc.p.meta.name));
- debugln!("Parser::parse_subcommand: About to parse sc={}",
- sc.p.meta.name);
+ sc.p.meta.usage = Some(format!(
+ "{}{}{}",
+ self.meta.bin_name.as_ref().unwrap_or(&String::new()),
+ if self.meta.bin_name.is_some() {
+ &*mid_string
+ } else {
+ ""
+ },
+ &*sc.p.meta.name
+ ));
+ sc.p.meta.bin_name = Some(format!(
+ "{}{}{}",
+ self.meta.bin_name.as_ref().unwrap_or(&String::new()),
+ if self.meta.bin_name.is_some() {
+ " "
+ } else {
+ ""
+ },
+ &*sc.p.meta.name
+ ));
+ debugln!(
+ "Parser::parse_subcommand: About to parse sc={}",
+ sc.p.meta.name
+ );
debugln!("Parser::parse_subcommand: sc settings={:#?}", sc.p.settings);
sc.p.get_matches_with(&mut sc_matcher, it)?;
matcher.subcommand(SubCommand {
- name: sc.p.meta.name.clone(),
- matches: sc_matcher.into(),
- });
+ name: sc.p.meta.name.clone(),
+ matches: sc_matcher.into(),
+ });
}
Ok(())
}
@@ -1213,10 +1279,11 @@ impl<'a, 'b> Parser<'a, 'b>
let mut args = vec![];
for n in &self.groups
- .iter()
- .find(|g| g.name == group)
- .expect(INTERNAL_ERROR_MSG)
- .args {
+ .iter()
+ .find(|g| g.name == group)
+ .expect(INTERNAL_ERROR_MSG)
+ .args
+ {
if let Some(f) = self.flags.iter().find(|f| &f.b.name == n) {
args.push(f.to_string());
} else if let Some(f) = self.opts.iter().find(|o| &o.b.name == n) {
@@ -1240,10 +1307,11 @@ impl<'a, 'b> Parser<'a, 'b>
let mut args = vec![];
for n in &self.groups
- .iter()
- .find(|g| g.name == group)
- .expect(INTERNAL_ERROR_MSG)
- .args {
+ .iter()
+ .find(|g| g.name == group)
+ .expect(INTERNAL_ERROR_MSG)
+ .args
+ {
if self.groups.iter().any(|g| g.name == *n) {
args.extend(self.arg_names_in_group(n));
g_vec.push(*n);
@@ -1297,12 +1365,14 @@ impl<'a, 'b> Parser<'a, 'b>
};
self.flags.push(arg);
}
- if !self.subcommands.is_empty() && !self.is_set(AS::DisableHelpSubcommand) &&
- self.is_set(AS::NeedsSubcommandHelp) {
+ if !self.subcommands.is_empty() && !self.is_set(AS::DisableHelpSubcommand)
+ && self.is_set(AS::NeedsSubcommandHelp)
+ {
debugln!("Parser::create_help_and_version: Building help");
- self.subcommands
- .push(App::new("help")
- .about("Prints this message or the help of the given subcommand(s)"));
+ self.subcommands.push(
+ App::new("help")
+ .about("Prints this message or the help of the given subcommand(s)"),
+ );
}
}
@@ -1310,8 +1380,10 @@ impl<'a, 'b> Parser<'a, 'b>
// because those will be listed in self.required
fn check_for_help_and_version_str(&self, arg: &OsStr) -> ClapResult<()> {
debugln!("Parser::check_for_help_and_version_str;");
- debug!("Parser::check_for_help_and_version_str: Checking if --{} is help or version...",
- arg.to_str().unwrap());
+ debug!(
+ "Parser::check_for_help_and_version_str: Checking if --{} is help or version...",
+ arg.to_str().unwrap()
+ );
if arg == "help" && self.is_set(AS::NeedsLongHelp) {
sdebugln!("Help");
return Err(self._help(true));
@@ -1327,8 +1399,10 @@ impl<'a, 'b> Parser<'a, 'b>
fn check_for_help_and_version_char(&self, arg: char) -> ClapResult<()> {
debugln!("Parser::check_for_help_and_version_char;");
- debug!("Parser::check_for_help_and_version_char: Checking if -{} is help or version...",
- arg);
+ debug!(
+ "Parser::check_for_help_and_version_char: Checking if -{} is help or version...",
+ arg
+ );
if let Some(h) = self.help_short {
if arg == h && self.is_set(AS::NeedsLongHelp) {
sdebugln!("Help");
@@ -1346,13 +1420,12 @@ impl<'a, 'b> Parser<'a, 'b>
}
fn use_long_help(&self) -> bool {
- self.meta.long_about.is_some() ||
- self.flags.iter().any(|f| f.b.long_help.is_some()) ||
- self.opts.iter().any(|o| o.b.long_help.is_some()) ||
- self.positionals.values().any(|p| p.b.long_help.is_some()) ||
- self.subcommands
- .iter()
- .any(|s| s.p.meta.long_about.is_some())
+ self.meta.long_about.is_some() || self.flags.iter().any(|f| f.b.long_help.is_some())
+ || self.opts.iter().any(|o| o.b.long_help.is_some())
+ || self.positionals.values().any(|p| p.b.long_help.is_some())
+ || self.subcommands
+ .iter()
+ .any(|s| s.p.meta.long_about.is_some())
}
fn _help(&self, mut use_long: bool) -> Error {
@@ -1365,7 +1438,7 @@ impl<'a, 'b> Parser<'a, 'b>
message: String::from_utf8(buf).unwrap_or_default(),
kind: ErrorKind::HelpDisplayed,
info: None,
- }
+ },
}
}
@@ -1379,14 +1452,15 @@ impl<'a, 'b> Parser<'a, 'b>
message: String::new(),
kind: ErrorKind::VersionDisplayed,
info: None,
- }
+ },
}
}
- fn parse_long_arg(&mut self,
- matcher: &mut ArgMatcher<'a>,
- full_arg: &OsStr)
- -> ClapResult> {
+ fn parse_long_arg(
+ &mut self,
+ matcher: &mut ArgMatcher<'a>,
+ full_arg: &OsStr,
+ ) -> ClapResult> {
// maybe here lifetime should be 'a
debugln!("Parser::parse_long_arg;");
let mut val = None;
@@ -1402,8 +1476,10 @@ impl<'a, 'b> Parser<'a, 'b>
};
if let Some(opt) = find_opt_by_long!(@os self, arg) {
- debugln!("Parser::parse_long_arg: Found valid opt '{}'",
- opt.to_string());
+ debugln!(
+ "Parser::parse_long_arg: Found valid opt '{}'",
+ opt.to_string()
+ );
self.settings.set(AS::ValidArgFound);
let ret = self.parse_opt(val, opt, val.is_some(), matcher)?;
if self.cache.map_or(true, |name| name != opt.b.name) {
@@ -1413,8 +1489,10 @@ impl<'a, 'b> Parser<'a, 'b>
return Ok(ret);
} else if let Some(flag) = find_flag_by_long!(@os self, arg) {
- debugln!("Parser::parse_long_arg: Found valid flag '{}'",
- flag.to_string());
+ debugln!(
+ "Parser::parse_long_arg: Found valid flag '{}'",
+ flag.to_string()
+ );
self.settings.set(AS::ValidArgFound);
// Only flags could be help or version, and we need to check the raw long
// so this is the first point to check
@@ -1441,10 +1519,11 @@ impl<'a, 'b> Parser<'a, 'b>
}
#[cfg_attr(feature = "lints", allow(len_zero))]
- fn parse_short_arg(&mut self,
- matcher: &mut ArgMatcher<'a>,
- full_arg: &OsStr)
- -> ClapResult> {
+ fn parse_short_arg(
+ &mut self,
+ matcher: &mut ArgMatcher<'a>,
+ full_arg: &OsStr,
+ ) -> ClapResult> {
debugln!("Parser::parse_short_arg: full_arg={:?}", full_arg);
let arg_os = full_arg.trim_left_matches(b'-');
let arg = arg_os.to_string_lossy();
@@ -1453,8 +1532,10 @@ impl<'a, 'b> Parser<'a, 'b>
// `-v` `-a` `-l` assuming `v` `a` and `l` are all, or mostly, valid shorts.
if self.is_set(AS::AllowLeadingHyphen) {
if arg.chars().any(|c| !self.contains_short(c)) {
- debugln!("Parser::parse_short_arg: LeadingHyphenAllowed yet -{} isn't valid",
- arg);
+ debugln!(
+ "Parser::parse_short_arg: LeadingHyphenAllowed yet -{} isn't valid",
+ arg
+ );
return Ok(ParseResult::MaybeHyphenValue);
}
} else if self.is_set(AS::ValidNegNumFound) {
@@ -1476,16 +1557,20 @@ impl<'a, 'b> Parser<'a, 'b>
self.settings.set(AS::ValidArgFound);
// Check for trailing concatenated value
let p: Vec<_> = arg.splitn(2, c).collect();
- debugln!("Parser::parse_short_arg:iter:{}: p[0]={:?}, p[1]={:?}",
- c,
- p[0].as_bytes(),
- p[1].as_bytes());
+ debugln!(
+ "Parser::parse_short_arg:iter:{}: p[0]={:?}, p[1]={:?}",
+ c,
+ p[0].as_bytes(),
+ p[1].as_bytes()
+ );
let i = p[0].as_bytes().len() + 1;
let val = if p[1].as_bytes().len() > 0 {
- debugln!("Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii)",
- c,
- arg_os.split_at(i).1.as_bytes(),
- arg_os.split_at(i).1);
+ debugln!(
+ "Parser::parse_short_arg:iter:{}: val={:?} (bytes), val={:?} (ascii)",
+ c,
+ arg_os.split_at(i).1.as_bytes(),
+ arg_os.split_at(i).1
+ );
Some(arg_os.split_at(i).1)
} else {
None
@@ -1515,23 +1600,24 @@ impl<'a, 'b> Parser<'a, 'b>
}
} else {
let arg = format!("-{}", c);
- return Err(Error::unknown_argument(&*arg,
- "",
- &*usage::create_error_usage(self,
- matcher,
- None),
- self.color()));
+ return Err(Error::unknown_argument(
+ &*arg,
+ "",
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
}
Ok(ret)
}
- fn parse_opt(&self,
- val: Option<&OsStr>,
- opt: &OptBuilder<'a, 'b>,
- had_eq: bool,
- matcher: &mut ArgMatcher<'a>)
- -> ClapResult> {
+ fn parse_opt(
+ &self,
+ val: Option<&OsStr>,
+ opt: &OptBuilder<'a, 'b>,
+ had_eq: bool,
+ matcher: &mut ArgMatcher<'a>,
+ ) -> ClapResult> {
debugln!("Parser::parse_opt; opt={}, val={:?}", opt.b.name, val);
debugln!("Parser::parse_opt; opt.settings={:?}", opt.b.settings);
let mut has_eq = false;
@@ -1544,24 +1630,28 @@ impl<'a, 'b> Parser<'a, 'b>
if let Some(fv) = val {
has_eq = fv.starts_with(&[b'=']) || had_eq;
let v = fv.trim_left_matches(b'=');
- if !empty_vals &&
- (v.len_() == 0 || (needs_eq && !has_eq)) {
+ if !empty_vals && (v.len_() == 0 || (needs_eq && !has_eq)) {
sdebugln!("Found Empty - Error");
- return Err(Error::empty_value(opt,
- &*usage::create_error_usage(self, matcher, None),
- self.color()));
+ return Err(Error::empty_value(
+ opt,
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
}
sdebugln!("Found - {:?}, len: {}", v, v.len_());
- debugln!("Parser::parse_opt: {:?} contains '='...{:?}",
- fv,
- fv.starts_with(&[b'=']));
+ debugln!(
+ "Parser::parse_opt: {:?} contains '='...{:?}",
+ fv,
+ fv.starts_with(&[b'='])
+ );
self.add_val_to_arg(opt, v, matcher)?;
} else if needs_eq && !(empty_vals || min_vals_zero) {
sdebugln!("None, but requires equals...Error");
- return Err(Error::empty_value(opt,
- &*usage::create_error_usage(self, matcher, None),
- self.color()));
-
+ return Err(Error::empty_value(
+ opt,
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ));
} else {
sdebugln!("None");
}
@@ -1584,17 +1674,21 @@ impl<'a, 'b> Parser<'a, 'b>
Ok(ParseResult::ValuesDone)
}
- fn add_val_to_arg(&self,
- arg: &A,
- val: &OsStr,
- matcher: &mut ArgMatcher<'a>)
- -> ClapResult>
- where A: AnyArg<'a, 'b> + Display
+ fn add_val_to_arg(
+ &self,
+ arg: &A,
+ val: &OsStr,
+ matcher: &mut ArgMatcher<'a>,
+ ) -> ClapResult>
+ where
+ A: AnyArg<'a, 'b> + Display,
{
debugln!("Parser::add_val_to_arg; arg={}, val={:?}", arg.name(), val);
- debugln!("Parser::add_val_to_arg; trailing_vals={:?}, DontDelimTrailingVals={:?}",
- self.is_set(AS::TrailingValues),
- self.is_set(AS::DontDelimitTrailingValues));
+ debugln!(
+ "Parser::add_val_to_arg; trailing_vals={:?}, DontDelimTrailingVals={:?}",
+ self.is_set(AS::TrailingValues),
+ self.is_set(AS::DontDelimitTrailingValues)
+ );
if !(self.is_set(AS::TrailingValues) && self.is_set(AS::DontDelimitTrailingValues)) {
if let Some(delim) = arg.val_delim() {
if val.is_empty_() {
@@ -1605,10 +1699,11 @@ impl<'a, 'b> Parser<'a, 'b>
iret = self.add_single_val_to_arg(arg, v, matcher)?;
}
// If there was a delimiter used, we're not looking for more values
- if val.contains_byte(delim as u32 as u8) ||
- arg.is_set(ArgSettings::RequireDelimiter) {
- iret = ParseResult::ValuesDone;
- }
+ if val.contains_byte(delim as u32 as u8)
+ || arg.is_set(ArgSettings::RequireDelimiter)
+ {
+ iret = ParseResult::ValuesDone;
+ }
Ok(iret)
}
} else {
@@ -1619,12 +1714,14 @@ impl<'a, 'b> Parser<'a, 'b>
}
}
- fn add_single_val_to_arg(&self,
- arg: &A,
- v: &OsStr,
- matcher: &mut ArgMatcher<'a>)
- -> ClapResult>
- where A: AnyArg<'a, 'b> + Display
+ fn add_single_val_to_arg(
+ &self,
+ arg: &A,
+ v: &OsStr,
+ matcher: &mut ArgMatcher<'a>,
+ ) -> ClapResult>
+ where
+ A: AnyArg<'a, 'b> + Display,
{
debugln!("Parser::add_single_val_to_arg;");
debugln!("Parser::add_single_val_to_arg: adding val...{:?}", v);
@@ -1649,10 +1746,11 @@ impl<'a, 'b> Parser<'a, 'b>
}
- fn parse_flag(&self,
- flag: &FlagBuilder<'a, 'b>,
- matcher: &mut ArgMatcher<'a>)
- -> ClapResult> {
+ fn parse_flag(
+ &self,
+ flag: &FlagBuilder<'a, 'b>,
+ matcher: &mut ArgMatcher<'a>,
+ ) -> ClapResult> {
debugln!("Parser::parse_flag;");
matcher.inc_occurrence_of(flag.b.name);
@@ -1664,10 +1762,8 @@ impl<'a, 'b> Parser<'a, 'b>
}
fn did_you_mean_error(&self, arg: &str, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
-
// Didn't match a flag or option
- let suffix =
- suggestions::did_you_mean_flag_suffix(arg, longs!(self), &self.subcommands);
+ let suffix = suggestions::did_you_mean_flag_suffix(arg, longs!(self), &self.subcommands);
// Add the arg to the matches to build a proper usage string
if let Some(name) = suffix.1 {
@@ -1683,10 +1779,12 @@ impl<'a, 'b> Parser<'a, 'b>
}
let used_arg = format!("--{}", arg);
- Err(Error::unknown_argument(&*used_arg,
- &*suffix.0,
- &*usage::create_error_usage(self, matcher, None),
- self.color()))
+ Err(Error::unknown_argument(
+ &*used_arg,
+ &*suffix.0,
+ &*usage::create_error_usage(self, matcher, None),
+ self.color(),
+ ))
}
// Prints the version to the user and exits if quit=true
@@ -1889,7 +1987,8 @@ impl<'a, 'b> Parser<'a, 'b>
/// Check is a given string matches the binary name for this parser
fn is_bin_name(&self, value: &str) -> bool {
- self.meta.bin_name
+ self.meta
+ .bin_name
.as_ref()
.and_then(|name| Some(value == name))
.unwrap_or(false)
@@ -1897,7 +1996,8 @@ impl<'a, 'b> Parser<'a, 'b>
/// Check is a given string is an alias for this parser
fn is_alias(&self, value: &str) -> bool {
- self.meta.aliases
+ self.meta
+ .aliases
.as_ref()
.and_then(|aliases| {
for alias in aliases {
@@ -1914,8 +2014,10 @@ impl<'a, 'b> Parser<'a, 'b>
#[cfg_attr(feature = "lints", allow(block_in_if_condition_stmt))]
pub fn find_subcommand(&'b self, sc: &str) -> Option<&'b App<'a, 'b>> {
debugln!("Parser::find_subcommand: sc={}", sc);
- debugln!("Parser::find_subcommand: Currently in Parser...{}",
- self.meta.bin_name.as_ref().unwrap());
+ debugln!(
+ "Parser::find_subcommand: Currently in Parser...{}",
+ self.meta.bin_name.as_ref().unwrap()
+ );
for s in &self.subcommands {
if s.p.is_bin_name(sc) {
return Some(s);
diff --git a/src/app/settings.rs b/src/app/settings.rs
index 92c685f2..1b304225 100644
--- a/src/app/settings.rs
+++ b/src/app/settings.rs
@@ -1,5 +1,5 @@
// Std
-#[allow(unused_imports)]
+#[allow(unused_imports)]
use std::ascii::AsciiExt;
use std::str::FromStr;
use std::ops::BitOr;
@@ -60,7 +60,10 @@ impl BitOr for AppFlags {
impl Default for AppFlags {
fn default() -> Self {
- AppFlags(Flags::NEEDS_LONG_VERSION | Flags::NEEDS_LONG_HELP | Flags::NEEDS_SC_HELP | Flags::UTF8_NONE | Flags::COLOR_AUTO)
+ AppFlags(
+ Flags::NEEDS_LONG_VERSION | Flags::NEEDS_LONG_HELP | Flags::NEEDS_SC_HELP
+ | Flags::UTF8_NONE | Flags::COLOR_AUTO,
+ )
}
}
@@ -138,8 +141,8 @@ pub enum AppSettings {
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, AppSettings};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
@@ -592,9 +595,9 @@ pub enum AppSettings {
NextLineHelp,
/// **DEPRECATED**: This setting is no longer required in order to propagate values up or down
- ///
+ ///
/// Specifies that the parser should propagate global arg's values down or up through any *used*
- /// child subcommands. Meaning, if a subcommand wasn't used, the values won't be propagated to
+ /// child subcommands. Meaning, if a subcommand wasn't used, the values won't be propagated to
/// said subcommand.
///
/// # Examples
@@ -710,8 +713,8 @@ pub enum AppSettings {
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, AppSettings, ErrorKind};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::OsStringExt;
@@ -839,32 +842,23 @@ pub enum AppSettings {
/// [`SubCommand`]: ./struct.SubCommand.html
WaitOnError,
- #[doc(hidden)]
- NeedsLongVersion,
+ #[doc(hidden)] NeedsLongVersion,
- #[doc(hidden)]
- NeedsLongHelp,
+ #[doc(hidden)] NeedsLongHelp,
- #[doc(hidden)]
- NeedsSubcommandHelp,
+ #[doc(hidden)] NeedsSubcommandHelp,
- #[doc(hidden)]
- LowIndexMultiplePositional,
+ #[doc(hidden)] LowIndexMultiplePositional,
- #[doc(hidden)]
- TrailingValues,
+ #[doc(hidden)] TrailingValues,
- #[doc(hidden)]
- ValidNegNumFound,
+ #[doc(hidden)] ValidNegNumFound,
- #[doc(hidden)]
- Propagated,
+ #[doc(hidden)] Propagated,
- #[doc(hidden)]
- ValidArgFound,
+ #[doc(hidden)] ValidArgFound,
- #[doc(hidden)]
- ContainsLast,
+ #[doc(hidden)] ContainsLast,
}
impl FromStr for AppSettings {
@@ -916,74 +910,142 @@ mod test {
#[test]
fn app_settings_fromstr() {
- assert_eq!("argsnegatesubcommands".parse::().unwrap(),
- AppSettings::ArgsNegateSubcommands);
- assert_eq!("argrequiredelsehelp".parse::().unwrap(),
- AppSettings::ArgRequiredElseHelp);
- assert_eq!("allowexternalsubcommands".parse::().unwrap(),
- AppSettings::AllowExternalSubcommands);
- assert_eq!("allowinvalidutf8".parse::().unwrap(),
- AppSettings::AllowInvalidUtf8);
- assert_eq!("allowleadinghyphen".parse::().unwrap(),
- AppSettings::AllowLeadingHyphen);
- assert_eq!("allownegativenumbers".parse::().unwrap(),
- AppSettings::AllowNegativeNumbers);
- assert_eq!("coloredhelp".parse::().unwrap(),
- AppSettings::ColoredHelp);
- assert_eq!("colorauto".parse::().unwrap(),
- AppSettings::ColorAuto);
- assert_eq!("coloralways".parse::().unwrap(),
- AppSettings::ColorAlways);
- assert_eq!("colornever".parse::().unwrap(),
- AppSettings::ColorNever);
- assert_eq!("disablehelpsubcommand".parse::().unwrap(),
- AppSettings::DisableHelpSubcommand);
- assert_eq!("disableversion".parse::().unwrap(),
- AppSettings::DisableVersion);
- assert_eq!("dontcollapseargsinusage".parse::().unwrap(),
- AppSettings::DontCollapseArgsInUsage);
- assert_eq!("dontdelimittrailingvalues".parse::().unwrap(),
- AppSettings::DontDelimitTrailingValues);
- assert_eq!("derivedisplayorder".parse::().unwrap(),
- AppSettings::DeriveDisplayOrder);
- assert_eq!("globalversion".parse::().unwrap(),
- AppSettings::GlobalVersion);
- assert_eq!("hidden".parse::().unwrap(),
- AppSettings::Hidden);
- assert_eq!("hidepossiblevaluesinhelp".parse::().unwrap(),
- AppSettings::HidePossibleValuesInHelp);
- assert_eq!("lowindexmultiplePositional".parse::().unwrap(),
- AppSettings::LowIndexMultiplePositional);
- assert_eq!("nobinaryname".parse::().unwrap(),
- AppSettings::NoBinaryName);
- assert_eq!("nextlinehelp".parse::().unwrap(),
- AppSettings::NextLineHelp);
- assert_eq!("subcommandsnegatereqs".parse::().unwrap(),
- AppSettings::SubcommandsNegateReqs);
- assert_eq!("subcommandrequired".parse::().unwrap(),
- AppSettings::SubcommandRequired);
- assert_eq!("subcommandrequiredelsehelp".parse::().unwrap(),
- AppSettings::SubcommandRequiredElseHelp);
- assert_eq!("strictutf8".parse::().unwrap(),
- AppSettings::StrictUtf8);
- assert_eq!("trailingvararg".parse::().unwrap(),
- AppSettings::TrailingVarArg);
- assert_eq!("unifiedhelpmessage".parse::().unwrap(),
- AppSettings::UnifiedHelpMessage);
- assert_eq!("versionlesssubcommands".parse::().unwrap(),
- AppSettings::VersionlessSubcommands);
- assert_eq!("waitonerror".parse::().unwrap(),
- AppSettings::WaitOnError);
- assert_eq!("validnegnumfound".parse::().unwrap(),
- AppSettings::ValidNegNumFound);
- assert_eq!("validargfound".parse::().unwrap(),
- AppSettings::ValidArgFound);
- assert_eq!("propagated".parse::().unwrap(),
- AppSettings::Propagated);
- assert_eq!("trailingvalues".parse::().unwrap(),
- AppSettings::TrailingValues);
- assert_eq!("infersubcommands".parse::().unwrap(),
- AppSettings::InferSubcommands);
+ assert_eq!(
+ "argsnegatesubcommands".parse::().unwrap(),
+ AppSettings::ArgsNegateSubcommands
+ );
+ assert_eq!(
+ "argrequiredelsehelp".parse::().unwrap(),
+ AppSettings::ArgRequiredElseHelp
+ );
+ assert_eq!(
+ "allowexternalsubcommands".parse::().unwrap(),
+ AppSettings::AllowExternalSubcommands
+ );
+ assert_eq!(
+ "allowinvalidutf8".parse::().unwrap(),
+ AppSettings::AllowInvalidUtf8
+ );
+ assert_eq!(
+ "allowleadinghyphen".parse::().unwrap(),
+ AppSettings::AllowLeadingHyphen
+ );
+ assert_eq!(
+ "allownegativenumbers".parse::().unwrap(),
+ AppSettings::AllowNegativeNumbers
+ );
+ assert_eq!(
+ "coloredhelp".parse::().unwrap(),
+ AppSettings::ColoredHelp
+ );
+ assert_eq!(
+ "colorauto".parse::().unwrap(),
+ AppSettings::ColorAuto
+ );
+ assert_eq!(
+ "coloralways".parse::().unwrap(),
+ AppSettings::ColorAlways
+ );
+ assert_eq!(
+ "colornever".parse::().unwrap(),
+ AppSettings::ColorNever
+ );
+ assert_eq!(
+ "disablehelpsubcommand".parse::().unwrap(),
+ AppSettings::DisableHelpSubcommand
+ );
+ assert_eq!(
+ "disableversion".parse::().unwrap(),
+ AppSettings::DisableVersion
+ );
+ assert_eq!(
+ "dontcollapseargsinusage".parse::().unwrap(),
+ AppSettings::DontCollapseArgsInUsage
+ );
+ assert_eq!(
+ "dontdelimittrailingvalues".parse::().unwrap(),
+ AppSettings::DontDelimitTrailingValues
+ );
+ assert_eq!(
+ "derivedisplayorder".parse::().unwrap(),
+ AppSettings::DeriveDisplayOrder
+ );
+ assert_eq!(
+ "globalversion".parse::().unwrap(),
+ AppSettings::GlobalVersion
+ );
+ assert_eq!(
+ "hidden".parse::().unwrap(),
+ AppSettings::Hidden
+ );
+ assert_eq!(
+ "hidepossiblevaluesinhelp".parse::().unwrap(),
+ AppSettings::HidePossibleValuesInHelp
+ );
+ assert_eq!(
+ "lowindexmultiplePositional".parse::().unwrap(),
+ AppSettings::LowIndexMultiplePositional
+ );
+ assert_eq!(
+ "nobinaryname".parse::().unwrap(),
+ AppSettings::NoBinaryName
+ );
+ assert_eq!(
+ "nextlinehelp".parse::().unwrap(),
+ AppSettings::NextLineHelp
+ );
+ assert_eq!(
+ "subcommandsnegatereqs".parse::().unwrap(),
+ AppSettings::SubcommandsNegateReqs
+ );
+ assert_eq!(
+ "subcommandrequired".parse::().unwrap(),
+ AppSettings::SubcommandRequired
+ );
+ assert_eq!(
+ "subcommandrequiredelsehelp".parse::().unwrap(),
+ AppSettings::SubcommandRequiredElseHelp
+ );
+ assert_eq!(
+ "strictutf8".parse::().unwrap(),
+ AppSettings::StrictUtf8
+ );
+ assert_eq!(
+ "trailingvararg".parse::().unwrap(),
+ AppSettings::TrailingVarArg
+ );
+ assert_eq!(
+ "unifiedhelpmessage".parse::().unwrap(),
+ AppSettings::UnifiedHelpMessage
+ );
+ assert_eq!(
+ "versionlesssubcommands".parse::().unwrap(),
+ AppSettings::VersionlessSubcommands
+ );
+ assert_eq!(
+ "waitonerror".parse::().unwrap(),
+ AppSettings::WaitOnError
+ );
+ assert_eq!(
+ "validnegnumfound".parse::().unwrap(),
+ AppSettings::ValidNegNumFound
+ );
+ assert_eq!(
+ "validargfound".parse::().unwrap(),
+ AppSettings::ValidArgFound
+ );
+ assert_eq!(
+ "propagated".parse::().unwrap(),
+ AppSettings::Propagated
+ );
+ assert_eq!(
+ "trailingvalues".parse::().unwrap(),
+ AppSettings::TrailingValues
+ );
+ assert_eq!(
+ "infersubcommands".parse::().unwrap(),
+ AppSettings::InferSubcommands
+ );
assert!("hahahaha".parse::().is_err());
}
}
diff --git a/src/app/usage.rs b/src/app/usage.rs
index cd2fb3bb..60905884 100644
--- a/src/app/usage.rs
+++ b/src/app/usage.rs
@@ -19,11 +19,13 @@ pub fn create_usage_with_title(p: &Parser, used: &[&str]) -> String {
}
// Creates a usage string to be used in error message (i.e. one with currently used args)
-pub fn create_error_usage<'a, 'b>(p: &Parser<'a, 'b>,
- matcher: &'b ArgMatcher<'a>,
- extra: Option<&str>)
- -> String {
- let mut args: Vec<_> = matcher.arg_names()
+pub fn create_error_usage<'a, 'b>(
+ p: &Parser<'a, 'b>,
+ matcher: &'b ArgMatcher<'a>,
+ extra: Option<&str>,
+) -> String {
+ let mut args: Vec<_> = matcher
+ .arg_names()
.iter()
.filter(|n| {
if let Some(o) = find_by_name!(p, **n, opts, iter) {
@@ -60,20 +62,15 @@ pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String {
let name = p.meta
.usage
.as_ref()
- .unwrap_or_else(|| {
- p.meta
- .bin_name
- .as_ref()
- .unwrap_or(&p.meta.name)
- });
+ .unwrap_or_else(|| p.meta.bin_name.as_ref().unwrap_or(&p.meta.name));
usage.push_str(&*name);
let req_string = if incl_reqs {
let mut reqs: Vec<&str> = p.required().map(|r| &**r).collect();
reqs.sort();
reqs.dedup();
- get_required_usage_from(p, &reqs, None, None, false).iter().fold(String::new(), |a, s| {
- a + &format!(" {}", s)[..]
- })
+ get_required_usage_from(p, &reqs, None, None, false)
+ .iter()
+ .fold(String::new(), |a, s| a + &format!(" {}", s)[..])
} else {
String::new()
};
@@ -84,8 +81,9 @@ pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String {
} else if flags {
usage.push_str(" [OPTIONS]");
}
- if !p.is_set(AS::UnifiedHelpMessage) &&
- p.opts.iter().any(|o| !o.is_set(ArgSettings::Required) && !o.is_set(ArgSettings::Hidden)) {
+ if !p.is_set(AS::UnifiedHelpMessage) && p.opts.iter().any(|o| {
+ !o.is_set(ArgSettings::Required) && !o.is_set(ArgSettings::Hidden)
+ }) {
usage.push_str(" [OPTIONS]");
}
@@ -94,13 +92,19 @@ pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String {
let has_last = p.positionals.values().any(|p| p.is_set(ArgSettings::Last));
// places a '--' in the usage string if there are args and options
// supporting multiple values
- if p.opts.iter().any(|o| o.is_set(ArgSettings::Multiple)) &&
- p.positionals.values().any(|p| !p.is_set(ArgSettings::Required)) &&
- !(p.has_visible_subcommands() || p.is_set(AS::AllowExternalSubcommands)) && !has_last {
+ if p.opts.iter().any(|o| o.is_set(ArgSettings::Multiple))
+ && p.positionals
+ .values()
+ .any(|p| !p.is_set(ArgSettings::Required))
+ && !(p.has_visible_subcommands() || p.is_set(AS::AllowExternalSubcommands))
+ && !has_last
+ {
usage.push_str(" [--]");
}
- let not_req_or_hidden =
- |p: &PosBuilder| (!p.is_set(ArgSettings::Required) || p.is_set(ArgSettings::Last)) && !p.is_set(ArgSettings::Hidden);
+ let not_req_or_hidden = |p: &PosBuilder| {
+ (!p.is_set(ArgSettings::Required) || p.is_set(ArgSettings::Last))
+ && !p.is_set(ArgSettings::Hidden)
+ };
if p.has_positionals() && p.positionals.values().any(not_req_or_hidden) {
if let Some(args_tag) = get_args_tag(p, incl_reqs) {
usage.push_str(&*args_tag);
@@ -114,7 +118,11 @@ pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String {
.expect(INTERNAL_ERROR_MSG);
debugln!("usage::create_help_usage: '{}' has .last(true)", pos.name());
let req = pos.is_set(ArgSettings::Required);
- if req && p.positionals.values().any(|p| !p.is_set(ArgSettings::Required)) {
+ if req
+ && p.positionals
+ .values()
+ .any(|p| !p.is_set(ArgSettings::Required))
+ {
usage.push_str(" -- <");
} else if req {
usage.push_str(" [--] <");
@@ -161,21 +169,16 @@ fn create_smart_usage(p: &Parser, used: &[&str]) -> String {
let mut hs: Vec<&str> = p.required().map(|s| &**s).collect();
hs.extend_from_slice(used);
- let r_string =
- get_required_usage_from(p, &hs, None, None, false).iter().fold(String::new(), |acc, s| {
- acc + &format!(" {}", s)[..]
- });
+ let r_string = get_required_usage_from(p, &hs, None, None, false)
+ .iter()
+ .fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]);
- usage.push_str(&p.meta
- .usage
- .as_ref()
- .unwrap_or_else(|| {
- p.meta
- .bin_name
- .as_ref()
- .unwrap_or(&p.meta.name)
- })
- [..]);
+ usage.push_str(
+ &p.meta
+ .usage
+ .as_ref()
+ .unwrap_or_else(|| p.meta.bin_name.as_ref().unwrap_or(&p.meta.name))[..],
+ );
usage.push_str(&*r_string);
if p.is_set(AS::SubcommandRequired) {
usage.push_str(" ");
@@ -189,10 +192,11 @@ fn get_args_tag(p: &Parser, incl_reqs: bool) -> Option {
debugln!("usage::get_args_tag;");
let mut count = 0;
'outer: for pos in p.positionals
- .values()
- .filter(|pos| !pos.is_set(ArgSettings::Required))
- .filter(|pos| !pos.is_set(ArgSettings::Hidden))
- .filter(|pos| !pos.is_set(ArgSettings::Last)) {
+ .values()
+ .filter(|pos| !pos.is_set(ArgSettings::Required))
+ .filter(|pos| !pos.is_set(ArgSettings::Hidden))
+ .filter(|pos| !pos.is_set(ArgSettings::Last))
+ {
debugln!("usage::get_args_tag:iter:{}:", pos.b.name);
if let Some(g_vec) = p.groups_for_arg(pos.b.name) {
for grp_s in &g_vec {
@@ -204,8 +208,10 @@ fn get_args_tag(p: &Parser, incl_reqs: bool) -> Option {
}
}
count += 1;
- debugln!("usage::get_args_tag:iter: {} Args not required or hidden",
- count);
+ debugln!(
+ "usage::get_args_tag:iter: {} Args not required or hidden",
+ count
+ );
}
if !p.is_set(AS::DontCollapseArgsInUsage) && count > 1 {
debugln!("usage::get_args_tag:iter: More than one, returning [ARGS]");
@@ -214,52 +220,65 @@ fn get_args_tag(p: &Parser, incl_reqs: bool) -> Option {
let pos = p.positionals
.values()
.find(|pos| {
- !pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Hidden) &&
- !pos.is_set(ArgSettings::Last)
- })
+ !pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Hidden)
+ && !pos.is_set(ArgSettings::Last)
+ })
.expect(INTERNAL_ERROR_MSG);
- debugln!("usage::get_args_tag:iter: Exactly one, returning '{}'",
- pos.name());
- return Some(format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str()));
+ debugln!(
+ "usage::get_args_tag:iter: Exactly one, returning '{}'",
+ pos.name()
+ );
+ return Some(format!(
+ " [{}]{}",
+ pos.name_no_brackets(),
+ pos.multiple_str()
+ ));
} else if p.is_set(AS::DontCollapseArgsInUsage) && !p.positionals.is_empty() && incl_reqs {
debugln!("usage::get_args_tag:iter: Don't collapse returning all");
- return Some(p.positionals
- .values()
- .filter(|pos| !pos.is_set(ArgSettings::Required))
- .filter(|pos| !pos.is_set(ArgSettings::Hidden))
- .filter(|pos| !pos.is_set(ArgSettings::Last))
- .map(|pos| {
- format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
- })
- .collect::>()
- .join(""));
+ return Some(
+ p.positionals
+ .values()
+ .filter(|pos| !pos.is_set(ArgSettings::Required))
+ .filter(|pos| !pos.is_set(ArgSettings::Hidden))
+ .filter(|pos| !pos.is_set(ArgSettings::Last))
+ .map(|pos| {
+ format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
+ })
+ .collect::>()
+ .join(""),
+ );
} else if !incl_reqs {
debugln!("usage::get_args_tag:iter: incl_reqs=false, building secondary usage string");
let highest_req_pos = p.positionals
.iter()
- .filter_map(|(idx, pos)| if pos.b.is_set(ArgSettings::Required) &&
- !pos.b.is_set(ArgSettings::Last) {
- Some(idx)
- } else {
- None
- })
+ .filter_map(|(idx, pos)| {
+ if pos.b.is_set(ArgSettings::Required) && !pos.b.is_set(ArgSettings::Last) {
+ Some(idx)
+ } else {
+ None
+ }
+ })
.max()
.unwrap_or_else(|| p.positionals.len());
- return Some(p.positionals
- .iter()
- .filter_map(|(idx, pos)| if idx <= highest_req_pos {
- Some(pos)
- } else {
- None
- })
- .filter(|pos| !pos.is_set(ArgSettings::Required))
- .filter(|pos| !pos.is_set(ArgSettings::Hidden))
- .filter(|pos| !pos.is_set(ArgSettings::Last))
- .map(|pos| {
- format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
- })
- .collect::>()
- .join(""));
+ return Some(
+ p.positionals
+ .iter()
+ .filter_map(|(idx, pos)| {
+ if idx <= highest_req_pos {
+ Some(pos)
+ } else {
+ None
+ }
+ })
+ .filter(|pos| !pos.is_set(ArgSettings::Required))
+ .filter(|pos| !pos.is_set(ArgSettings::Hidden))
+ .filter(|pos| !pos.is_set(ArgSettings::Last))
+ .map(|pos| {
+ format!(" [{}]{}", pos.name_no_brackets(), pos.multiple_str())
+ })
+ .collect::>()
+ .join(""),
+ );
}
Some("".into())
}
@@ -296,15 +315,18 @@ fn needs_flags_tag(p: &Parser) -> bool {
}
// Returns the required args in usage string form by fully unrolling all groups
-pub fn get_required_usage_from<'a, 'b>(p: &Parser<'a, 'b>,
- reqs: &[&'a str],
- matcher: Option<&ArgMatcher<'a>>,
- extra: Option<&str>,
- incl_last: bool)
- -> VecDeque {
- debugln!("usage::get_required_usage_from: reqs={:?}, extra={:?}",
- reqs,
- extra);
+pub fn get_required_usage_from<'a, 'b>(
+ p: &Parser<'a, 'b>,
+ reqs: &[&'a str],
+ matcher: Option<&ArgMatcher<'a>>,
+ extra: Option<&str>,
+ incl_last: bool,
+) -> VecDeque {
+ debugln!(
+ "usage::get_required_usage_from: reqs={:?}, extra={:?}",
+ reqs,
+ extra
+ );
let mut desc_reqs: Vec<&str> = vec![];
desc_reqs.extend(extra);
let mut new_reqs: Vec<&str> = vec![];
@@ -346,8 +368,10 @@ pub fn get_required_usage_from<'a, 'b>(p: &Parser<'a, 'b>,
get_requires!(@group a, new_reqs, reqs);
}
desc_reqs.extend_from_slice(&*new_reqs);
- debugln!("usage::get_required_usage_from: after init desc_reqs={:?}",
- desc_reqs);
+ debugln!(
+ "usage::get_required_usage_from: after init desc_reqs={:?}",
+ desc_reqs
+ );
loop {
let mut tmp = vec![];
for a in &new_reqs {
@@ -361,20 +385,26 @@ pub fn get_required_usage_from<'a, 'b>(p: &Parser<'a, 'b>,
break;
} else {
debugln!("usage::get_required_usage_from: after iter tmp={:?}", tmp);
- debugln!("usage::get_required_usage_from: after iter new_reqs={:?}",
- new_reqs);
+ debugln!(
+ "usage::get_required_usage_from: after iter new_reqs={:?}",
+ new_reqs
+ );
desc_reqs.extend_from_slice(&*new_reqs);
new_reqs.clear();
new_reqs.extend_from_slice(&*tmp);
- debugln!("usage::get_required_usage_from: after iter desc_reqs={:?}",
- desc_reqs);
+ debugln!(
+ "usage::get_required_usage_from: after iter desc_reqs={:?}",
+ desc_reqs
+ );
}
}
desc_reqs.extend_from_slice(reqs);
desc_reqs.sort();
desc_reqs.dedup();
- debugln!("usage::get_required_usage_from: final desc_reqs={:?}",
- desc_reqs);
+ debugln!(
+ "usage::get_required_usage_from: final desc_reqs={:?}",
+ desc_reqs
+ );
let mut ret_val = VecDeque::new();
let args_in_groups = p.groups
.iter()
@@ -383,7 +413,8 @@ pub fn get_required_usage_from<'a, 'b>(p: &Parser<'a, 'b>,
.collect::>();
let pmap = if let Some(m) = matcher {
- desc_reqs.iter()
+ desc_reqs
+ .iter()
.filter(|a| p.positionals.values().any(|p| &&p.b.name == a))
.filter(|&pos| !m.contains(pos))
.filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
@@ -392,7 +423,8 @@ pub fn get_required_usage_from<'a, 'b>(p: &Parser<'a, 'b>,
.map(|pos| (pos.index, pos))
.collect::>() // sort by index
} else {
- desc_reqs.iter()
+ desc_reqs
+ .iter()
.filter(|a| p.positionals.values().any(|pos| &&pos.b.name == a))
.filter_map(|pos| p.positionals.values().find(|x| &x.b.name == pos))
.filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last))
@@ -400,31 +432,39 @@ pub fn get_required_usage_from<'a, 'b>(p: &Parser<'a, 'b>,
.map(|pos| (pos.index, pos))
.collect::>() // sort by index
};
- debugln!("usage::get_required_usage_from: args_in_groups={:?}",
- args_in_groups);
+ debugln!(
+ "usage::get_required_usage_from: args_in_groups={:?}",
+ args_in_groups
+ );
for &p in pmap.values() {
let s = p.to_string();
if args_in_groups.is_empty() || !args_in_groups.contains(&&*s) {
ret_val.push_back(s);
}
}
- for a in desc_reqs.iter()
- .filter(|name| !p.positionals.values().any(|p| &&p.b.name == name))
- .filter(|name| !p.groups.iter().any(|g| &&g.name == name))
- .filter(|name| !args_in_groups.contains(name))
- .filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name))) {
+ for a in desc_reqs
+ .iter()
+ .filter(|name| !p.positionals.values().any(|p| &&p.b.name == name))
+ .filter(|name| !p.groups.iter().any(|g| &&g.name == name))
+ .filter(|name| !args_in_groups.contains(name))
+ .filter(|name| {
+ !(matcher.is_some() && matcher.as_ref().unwrap().contains(name))
+ }) {
debugln!("usage::get_required_usage_from:iter:{}:", a);
let arg = find_by_name!(p, *a, flags, iter)
.map(|f| f.to_string())
.unwrap_or_else(|| {
- find_by_name!(p, *a, opts, iter)
- .map(|o| o.to_string())
- .expect(INTERNAL_ERROR_MSG)
- });
+ find_by_name!(p, *a, opts, iter)
+ .map(|o| o.to_string())
+ .expect(INTERNAL_ERROR_MSG)
+ });
ret_val.push_back(arg);
}
let mut g_vec: Vec = vec![];
- for g in desc_reqs.iter().filter(|n| p.groups.iter().any(|g| &&g.name == n)) {
+ for g in desc_reqs
+ .iter()
+ .filter(|n| p.groups.iter().any(|g| &&g.name == n))
+ {
let g_string = p.args_in_group(g).join("|");
let elem = format!("<{}>", &g_string[..g_string.len()]);
if !g_vec.contains(&elem) {
diff --git a/src/app/validator.rs b/src/app/validator.rs
index 70eb266b..01373dd5 100644
--- a/src/app/validator.rs
+++ b/src/app/validator.rs
@@ -1,5 +1,7 @@
// std
use std::fmt::Display;
+#[allow(unused_imports)]
+use std::ascii::AsciiExt;
// Internal
use INTERNAL_ERROR_MSG;
@@ -10,22 +12,24 @@ use errors::{Error, ErrorKind};
use errors::Result as ClapResult;
use osstringext::OsStrExt2;
use app::settings::AppSettings as AS;
-use app::parser::{Parser, ParseResult};
+use app::parser::{ParseResult, Parser};
use fmt::{Colorizer, ColorizerOption};
use app::usage;
pub struct Validator<'a, 'b, 'z>(&'z mut Parser<'a, 'b>)
- where 'a: 'b,
- 'b: 'z;
+where
+ 'a: 'b,
+ 'b: 'z;
impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
pub fn new(p: &'z mut Parser<'a, 'b>) -> Self { Validator(p) }
- pub fn validate(&mut self,
- needs_val_of: ParseResult<'a>,
- subcmd_name: Option,
- matcher: &mut ArgMatcher<'a>)
- -> ClapResult<()> {
+ pub fn validate(
+ &mut self,
+ needs_val_of: ParseResult<'a>,
+ subcmd_name: Option,
+ matcher: &mut ArgMatcher<'a>,
+ ) -> ClapResult<()> {
debugln!("Validator::validate;");
let mut reqs_validated = false;
self.0.add_env(matcher)?;
@@ -45,21 +49,24 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
true
};
if should_err {
- return Err(Error::empty_value(o,
- &*usage::create_error_usage(self.0, matcher, None),
- self.0.color()));
+ return Err(Error::empty_value(
+ o,
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
}
- if matcher.is_empty() && matcher.subcommand_name().is_none() &&
- self.0.is_set(AS::ArgRequiredElseHelp) {
+ if matcher.is_empty() && matcher.subcommand_name().is_none()
+ && self.0.is_set(AS::ArgRequiredElseHelp)
+ {
let mut out = vec![];
self.0.write_help_err(&mut out)?;
return Err(Error {
- message: String::from_utf8_lossy(&*out).into_owned(),
- kind: ErrorKind::MissingArgumentOrSubcommand,
- info: None,
- });
+ message: String::from_utf8_lossy(&*out).into_owned(),
+ kind: ErrorKind::MissingArgumentOrSubcommand,
+ info: None,
+ });
}
self.validate_blacklist(matcher)?;
if !(self.0.is_set(AS::SubcommandsNegateReqs) && subcmd_name.is_some()) && !reqs_validated {
@@ -71,40 +78,54 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
Ok(())
}
- fn validate_values(&self,
- arg: &A,
- ma: &MatchedArg,
- matcher: &ArgMatcher<'a>)
- -> ClapResult<()>
- where A: AnyArg<'a, 'b> + Display
+ fn validate_values(
+ &self,
+ arg: &A,
+ ma: &MatchedArg,
+ matcher: &ArgMatcher<'a>,
+ ) -> ClapResult<()>
+ where
+ A: AnyArg<'a, 'b> + Display,
{
debugln!("Validator::validate_values: arg={:?}", arg.name());
for val in &ma.vals {
if self.0.is_set(AS::StrictUtf8) && val.to_str().is_none() {
- debugln!("Validator::validate_values: invalid UTF-8 found in val {:?}",
- val);
- return Err(Error::invalid_utf8(&*usage::create_error_usage(self.0, matcher, None),
- self.0.color()));
+ debugln!(
+ "Validator::validate_values: invalid UTF-8 found in val {:?}",
+ val
+ );
+ return Err(Error::invalid_utf8(
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
if let Some(p_vals) = arg.possible_vals() {
debugln!("Validator::validate_values: possible_vals={:?}", p_vals);
let val_str = val.to_string_lossy();
- if !p_vals.contains(&&*val_str) {
- return Err(Error::invalid_value(val_str,
- p_vals,
- arg,
- &*usage::create_error_usage(self.0,
- matcher,
- None),
- self.0.color()));
+ let ok = if arg.is_set(ArgSettings::CaseInsensitive) {
+ p_vals.iter().any(|pv| pv.eq_ignore_ascii_case(&*val_str))
+ } else {
+ p_vals.contains(&&*val_str)
+ };
+ if !ok {
+ return Err(Error::invalid_value(
+ val_str,
+ p_vals,
+ arg,
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
}
- if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_() &&
- matcher.contains(&*arg.name()) {
+ if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_()
+ && matcher.contains(&*arg.name())
+ {
debugln!("Validator::validate_values: illegal empty val found");
- return Err(Error::empty_value(arg,
- &*usage::create_error_usage(self.0, matcher, None),
- self.0.color()));
+ return Err(Error::empty_value(
+ arg,
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
if let Some(vtor) = arg.validator() {
debug!("Validator::validate_values: checking validator...");
@@ -119,9 +140,11 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
debug!("Validator::validate_values: checking validator_os...");
if let Err(e) = vtor(val) {
sdebugln!("error");
- return Err(Error::value_validation(Some(arg),
- (*e).to_string_lossy().to_string(),
- self.0.color()));
+ return Err(Error::value_validation(
+ Some(arg),
+ (*e).to_string_lossy().to_string(),
+ self.0.color(),
+ ));
} else {
sdebugln!("good");
}
@@ -131,8 +154,10 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
}
fn validate_blacklist(&self, matcher: &mut ArgMatcher) -> ClapResult<()> {
- debugln!("Validator::validate_blacklist: blacklist={:?}",
- self.0.blacklist);
+ debugln!(
+ "Validator::validate_blacklist: blacklist={:?}",
+ self.0.blacklist
+ );
macro_rules! build_err {
($p:expr, $name:expr, $matcher:ident) => ({
debugln!("build_err!: name={}", $name);
@@ -166,19 +191,36 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
}
for name in &self.0.blacklist {
- debugln!("Validator::validate_blacklist:iter:{}: Checking blacklisted arg", name);
+ debugln!(
+ "Validator::validate_blacklist:iter:{}: Checking blacklisted arg",
+ name
+ );
let mut should_err = false;
if self.0.groups.iter().any(|g| &g.name == name) {
- debugln!("Validator::validate_blacklist:iter:{}: groups contains it...", name);
+ debugln!(
+ "Validator::validate_blacklist:iter:{}: groups contains it...",
+ name
+ );
for n in self.0.arg_names_in_group(name) {
- debugln!("Validator::validate_blacklist:iter:{}:iter:{}: looking in group...", name, n);
+ debugln!(
+ "Validator::validate_blacklist:iter:{}:iter:{}: looking in group...",
+ name,
+ n
+ );
if matcher.contains(n) {
- debugln!("Validator::validate_blacklist:iter:{}:iter:{}: matcher contains it...", name, n);
+ debugln!(
+ "Validator::validate_blacklist:iter:{}:iter:{}: matcher contains it...",
+ name,
+ n
+ );
return Err(build_err!(self.0, n, matcher));
}
}
} else if let Some(ma) = matcher.get(name) {
- debugln!("Validator::validate_blacklist:iter:{}: matcher contains it...", name);
+ debugln!(
+ "Validator::validate_blacklist:iter:{}: matcher contains it...",
+ name
+ );
should_err = ma.occurs > 0;
}
if should_err {
@@ -191,9 +233,11 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
fn validate_matched_args(&self, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
debugln!("Validator::validate_matched_args;");
for (name, ma) in matcher.iter() {
- debugln!("Validator::validate_matched_args:iter:{}: vals={:#?}",
- name,
- ma.vals);
+ debugln!(
+ "Validator::validate_matched_args:iter:{}: vals={:#?}",
+ name,
+ ma.vals
+ );
if let Some(opt) = find_by_name!(self.0, *name, opts, iter) {
self.validate_arg_num_vals(opt, ma, matcher)?;
self.validate_values(opt, ma, matcher)?;
@@ -223,31 +267,35 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
Ok(())
}
- fn validate_arg_num_occurs(&self,
- a: &A,
- ma: &MatchedArg,
- matcher: &ArgMatcher)
- -> ClapResult<()>
- where A: AnyArg<'a, 'b> + Display
+ fn validate_arg_num_occurs(
+ &self,
+ a: &A,
+ ma: &MatchedArg,
+ matcher: &ArgMatcher,
+ ) -> ClapResult<()>
+ where
+ A: AnyArg<'a, 'b> + Display,
{
debugln!("Validator::validate_arg_num_occurs: a={};", a.name());
if ma.occurs > 1 && !a.is_set(ArgSettings::Multiple) {
// Not the first time, and we don't allow multiples
- return Err(Error::unexpected_multiple_usage(a,
- &*usage::create_error_usage(self.0,
- matcher,
- None),
- self.0.color()));
+ return Err(Error::unexpected_multiple_usage(
+ a,
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
Ok(())
}
- fn validate_arg_num_vals(&self,
- a: &A,
- ma: &MatchedArg,
- matcher: &ArgMatcher)
- -> ClapResult<()>
- where A: AnyArg<'a, 'b> + Display
+ fn validate_arg_num_vals(
+ &self,
+ a: &A,
+ ma: &MatchedArg,
+ matcher: &ArgMatcher,
+ ) -> ClapResult<()>
+ where
+ A: AnyArg<'a, 'b> + Display,
{
debugln!("Validator::validate_arg_num_vals;");
if let Some(num) = a.num_vals() {
@@ -259,74 +307,79 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
};
if should_err {
debugln!("Validator::validate_arg_num_vals: Sending error WrongNumberOfValues");
- return Err(Error::wrong_number_of_values(a,
- num,
- if a.is_set(ArgSettings::Multiple) {
- (ma.vals.len() % num as usize)
- } else {
- ma.vals.len()
- },
- if ma.vals.len() == 1 ||
- (a.is_set(ArgSettings::Multiple) &&
- (ma.vals.len() % num as usize) ==
- 1) {
- "as"
- } else {
- "ere"
- },
- &*usage::create_error_usage(self.0,
- matcher,
- None),
- self.0.color()));
+ return Err(Error::wrong_number_of_values(
+ a,
+ num,
+ if a.is_set(ArgSettings::Multiple) {
+ (ma.vals.len() % num as usize)
+ } else {
+ ma.vals.len()
+ },
+ if ma.vals.len() == 1
+ || (a.is_set(ArgSettings::Multiple) && (ma.vals.len() % num as usize) == 1)
+ {
+ "as"
+ } else {
+ "ere"
+ },
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
}
if let Some(num) = a.max_vals() {
debugln!("Validator::validate_arg_num_vals: max_vals set...{}", num);
if (ma.vals.len() as u64) > num {
debugln!("Validator::validate_arg_num_vals: Sending error TooManyValues");
- return Err(Error::too_many_values(ma.vals
- .iter()
- .last()
- .expect(INTERNAL_ERROR_MSG)
- .to_str()
- .expect(INVALID_UTF8),
- a,
- &*usage::create_error_usage(self.0,
- matcher,
- None),
- self.0.color()));
+ return Err(Error::too_many_values(
+ ma.vals
+ .iter()
+ .last()
+ .expect(INTERNAL_ERROR_MSG)
+ .to_str()
+ .expect(INVALID_UTF8),
+ a,
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
}
let min_vals_zero = if let Some(num) = a.min_vals() {
debugln!("Validator::validate_arg_num_vals: min_vals set: {}", num);
if (ma.vals.len() as u64) < num && num != 0 {
debugln!("Validator::validate_arg_num_vals: Sending error TooFewValues");
- return Err(Error::too_few_values(a,
- num,
- ma.vals.len(),
- &*usage::create_error_usage(self.0,
- matcher,
- None),
- self.0.color()));
+ return Err(Error::too_few_values(
+ a,
+ num,
+ ma.vals.len(),
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
num == 0
- } else { false };
+ } else {
+ false
+ };
// Issue 665 (https://github.com/kbknapp/clap-rs/issues/665)
// Issue 1105 (https://github.com/kbknapp/clap-rs/issues/1105)
if a.takes_value() && !min_vals_zero && ma.vals.is_empty() {
- return Err(Error::empty_value(a,
- &*usage::create_error_usage(self.0, matcher, None),
- self.0.color()));
+ return Err(Error::empty_value(
+ a,
+ &*usage::create_error_usage(self.0, matcher, None),
+ self.0.color(),
+ ));
}
Ok(())
}
- fn validate_arg_requires(&self,
- a: &A,
- ma: &MatchedArg,
- matcher: &ArgMatcher)
- -> ClapResult<()>
- where A: AnyArg<'a, 'b> + Display
+ fn validate_arg_requires(
+ &self,
+ a: &A,
+ ma: &MatchedArg,
+ matcher: &ArgMatcher,
+ ) -> ClapResult<()>
+ where
+ A: AnyArg<'a, 'b> + Display,
{
debugln!("Validator::validate_arg_requires;");
if let Some(a_reqs) = a.requires() {
@@ -342,8 +395,10 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
}
fn validate_required(&self, matcher: &ArgMatcher) -> ClapResult<()> {
- debugln!("Validator::validate_required: required={:?};",
- self.0.required);
+ debugln!(
+ "Validator::validate_required: required={:?};",
+ self.0.required
+ );
'outer: for name in &self.0.required {
debugln!("Validator::validate_required:iter:{}:", name);
if matcher.contains(name) {
@@ -377,25 +432,25 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
}
fn validate_conflicts(&self, a: &A, matcher: &ArgMatcher) -> Option
- where A: AnyArg<'a, 'b>
+ where
+ A: AnyArg<'a, 'b>,
{
debugln!("Validator::validate_conflicts: a={:?};", a.name());
- a.blacklist()
- .map(|bl| {
- bl.iter()
- .any(|conf| {
- matcher.contains(conf) ||
- self.0
- .groups
- .iter()
- .find(|g| &g.name == conf)
- .map_or(false, |g| g.args.iter().any(|arg| matcher.contains(arg)))
- })
+ a.blacklist().map(|bl| {
+ bl.iter().any(|conf| {
+ matcher.contains(conf)
+ || self.0
+ .groups
+ .iter()
+ .find(|g| &g.name == conf)
+ .map_or(false, |g| g.args.iter().any(|arg| matcher.contains(arg)))
})
+ })
}
fn validate_required_unless(&self, a: &A, matcher: &ArgMatcher) -> Option
- where A: AnyArg<'a, 'b>
+ where
+ A: AnyArg<'a, 'b>,
{
debugln!("Validator::validate_required_unless: a={:?};", a.name());
macro_rules! check {
@@ -426,11 +481,7 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
use_stderr: true,
when: self.0.color(),
});
- let mut reqs = self.0
- .required
- .iter()
- .map(|&r| &*r)
- .collect::>();
+ let mut reqs = self.0.required.iter().map(|&r| &*r).collect::>();
if let Some(r) = extra {
reqs.push(r);
}
@@ -440,22 +491,27 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> {
let req_args =
usage::get_required_usage_from(self.0, &reqs[..], Some(matcher), extra, true)
.iter()
- .fold(String::new(),
- |acc, s| acc + &format!("\n {}", c.error(s))[..]);
- debugln!("Validator::missing_required_error: req_args={:#?}",
- req_args);
- Err(Error::missing_required_argument(&*req_args,
- &*usage::create_error_usage(self.0, matcher, extra),
- self.0.color()))
+ .fold(String::new(), |acc, s| {
+ acc + &format!("\n {}", c.error(s))[..]
+ });
+ debugln!(
+ "Validator::missing_required_error: req_args={:#?}",
+ req_args
+ );
+ Err(Error::missing_required_argument(
+ &*req_args,
+ &*usage::create_error_usage(self.0, matcher, extra),
+ self.0.color(),
+ ))
}
#[inline]
fn is_missing_required_ok(&self, a: &A, matcher: &ArgMatcher) -> bool
- where A: AnyArg<'a, 'b>
+ where
+ A: AnyArg<'a, 'b>,
{
debugln!("Validator::is_missing_required_ok: a={}", a.name());
- self.validate_conflicts(a, matcher).unwrap_or(false) ||
- self.validate_required_unless(a, matcher)
- .unwrap_or(false)
+ self.validate_conflicts(a, matcher).unwrap_or(false)
+ || self.validate_required_unless(a, matcher).unwrap_or(false)
}
}
diff --git a/src/args/arg.rs b/src/args/arg.rs
index 5d8e0774..d6b92e34 100644
--- a/src/args/arg.rs
+++ b/src/args/arg.rs
@@ -1,10 +1,10 @@
#[cfg(feature = "yaml")]
use std::collections::BTreeMap;
use std::rc::Rc;
-use std::ffi::{OsString, OsStr};
-#[cfg(target_os="windows")]
+use std::ffi::{OsStr, OsString};
+#[cfg(target_os = "windows")]
use osstringext::OsStrExt3;
-#[cfg(not(target_os="windows"))]
+#[cfg(not(target_os = "windows"))]
use std::os::unix::ffi::OsStrExt;
use std::env;
@@ -14,7 +14,7 @@ use map::VecMap;
use usage_parser::UsageParser;
use args::settings::ArgSettings;
-use args::arg_builder::{Base, Valued, Switched};
+use args::arg_builder::{Base, Switched, Valued};
/// The abstract representation of a command line argument. Used to set all the options and
/// relationships that define a valid argument for the program.
@@ -41,18 +41,14 @@ use args::arg_builder::{Base, Valued, Switched};
#[allow(missing_debug_implementations)]
#[derive(Default, Clone)]
pub struct Arg<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
- #[doc(hidden)]
- pub b: Base<'a, 'b>,
- #[doc(hidden)]
- pub s: Switched<'b>,
- #[doc(hidden)]
- pub v: Valued<'a, 'b>,
- #[doc(hidden)]
- pub index: Option,
- #[doc(hidden)]
- pub r_ifs: Option>,
+ #[doc(hidden)] pub b: Base<'a, 'b>,
+ #[doc(hidden)] pub s: Switched<'b>,
+ #[doc(hidden)] pub v: Valued<'a, 'b>,
+ #[doc(hidden)] pub index: Option,
+ #[doc(hidden)] pub r_ifs: Option>,
}
impl<'a, 'b> Arg<'a, 'b> {
@@ -73,7 +69,12 @@ impl<'a, 'b> Arg<'a, 'b> {
/// ```
/// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
/// [`Arg`]: ./struct.Arg.html
- pub fn with_name(n: &'a str) -> Self { Arg { b: Base::new(n), ..Default::default() } }
+ pub fn with_name(n: &'a str) -> Self {
+ Arg {
+ b: Base::new(n),
+ ..Default::default()
+ }
+ }
/// Creates a new instance of [`Arg`] from a .yml (YAML) file.
///
@@ -143,11 +144,11 @@ impl<'a, 'b> Arg<'a, 'b> {
a.setb(ArgSettings::RequiredUnlessAll);
a
}
- s => {
- panic!("Unknown Arg setting '{}' in YAML file for arg '{}'",
- s,
- name_str)
- }
+ s => panic!(
+ "Unknown Arg setting '{}' in YAML file for arg '{}'",
+ s,
+ name_str
+ ),
}
}
@@ -605,10 +606,10 @@ impl<'a, 'b> Arg<'a, 'b> {
/// that cannot be read by this program. Obviously I'm going on
/// and on, so I'll stop now.
///
- /// -h, --help
+ /// -h, --help
/// Prints help information
///
- /// -V, --version
+ /// -V, --version
/// Prints version information
/// ```
/// [`Arg::help`]: ./struct.Arg.html#method.help
@@ -624,13 +625,13 @@ impl<'a, 'b> Arg<'a, 'b> {
/// allows one to access this arg early using the `--` syntax. Accessing an arg early, even with
/// the `--` syntax is otherwise not possible.
///
- /// **NOTE:** This will change the usage string to look like `$ prog [FLAGS] [-- ]` if
+ /// **NOTE:** This will change the usage string to look like `$ prog [FLAGS] [-- ]` if
/// `ARG` is marked as `.last(true)`.
///
/// **NOTE:** This setting will imply [`AppSettings::DontCollapseArgsInUsage`] because failing
/// to set this can make the usage string very confusing.
///
- /// **NOTE**: This setting only applies to positional arguments, and has no affect on FLAGS /
+ /// **NOTE**: This setting only applies to positional arguments, and has no affect on FLAGS /
/// OPTIONS
///
/// **CAUTION:** Setting an argument to `.last(true)` *and* having child subcommands is not
@@ -1891,10 +1892,10 @@ impl<'a, 'b> Arg<'a, 'b> {
/// **WARNING:**
///
/// Setting `multiple(true)` for an [option] with no other details, allows multiple values
- /// **and** multiple occurrences because it isn't possible to have more occurrences than values
- /// for options. Because multiple values are allowed, `--option val1 val2 val3` is perfectly
- /// valid, be careful when designing a CLI where positional arguments are expected after a
- /// option which accepts multiple values, as `clap` will continue parsing *values* until it
+ /// **and** multiple occurrences because it isn't possible to have more occurrences than values
+ /// for options. Because multiple values are allowed, `--option val1 val2 val3` is perfectly
+ /// valid, be careful when designing a CLI where positional arguments are expected after a
+ /// option which accepts multiple values, as `clap` will continue parsing *values* until it
/// reaches the max or specific number of values defined, or another flag or option.
///
/// **Pro Tip**:
@@ -1904,35 +1905,35 @@ impl<'a, 'b> Arg<'a, 'b> {
/// [`Arg::multiple(true)`].
///
/// **WARNING:**
- ///
+ ///
/// When using args with `multiple(true)` on [options] or [positionals] (i.e. those args that
/// accept values) and [subcommands], one needs to consider the posibility of an argument value
/// being the same as a valid subcommand. By default `clap` will parse the argument in question
/// as a value *only if* a value is possible at that moment. Otherwise it will be parsed as a
/// subcommand. In effect, this means using `multiple(true)` with no additional parameters and
- /// a possible value that coincides with a subcommand name, the subcommand cannot be called
+ /// a possible value that coincides with a subcommand name, the subcommand cannot be called
/// unless another argument is passed first.
- ///
+ ///
/// As an example, consider a CLI with an option `--ui-paths=...` and subcommand `signer`
- ///
+ ///
/// The following would be parsed as values to `--ui-paths`.
- ///
+ ///
/// ```notrust
/// $ program --ui-paths path1 path2 signer
/// ```
- ///
+ ///
/// This is because `--ui-paths` accepts multiple values. `clap` will continue parsing values
/// until another argument is reached and it knows `--ui-paths` is done.
- ///
+ ///
/// By adding additional parameters to `--ui-paths` we can solve this issue. Consider adding
- /// [`Arg::number_of_values(1)`] as discussed above. The following are all valid, and `signer`
+ /// [`Arg::number_of_values(1)`] as discussed above. The following are all valid, and `signer`
/// is parsed as both a subcommand and a value in the second case.
- ///
+ ///
/// ```notrust
/// $ program --ui-paths path1 signer
/// $ program --ui-paths path1 --ui-paths signer signer
/// ```
- ///
+ ///
/// # Examples
///
/// ```rust
@@ -2133,8 +2134,8 @@ impl<'a, 'b> Arg<'a, 'b> {
/// Specifies that an argument can be matched to all child [`SubCommand`]s.
///
/// **NOTE:** Global arguments *only* propagate down, **not** up (to parent commands), however
- /// their values once a user uses them will be propagated back up to parents. In effect, this
- /// means one should *define* all global arguments at the top level, however it doesn't matter
+ /// their values once a user uses them will be propagated back up to parents. In effect, this
+ /// means one should *define* all global arguments at the top level, however it doesn't matter
/// where the user *uses* the global argument.
///
/// # Examples
@@ -2390,6 +2391,59 @@ impl<'a, 'b> Arg<'a, 'b> {
self
}
+ /// When used with [`Arg::possible_values`] it allows the argument value to pass validation even if
+ /// the case differs from that of the specified `possible_value`.
+ ///
+ /// **Pro Tip:** Use this setting with [`arg_enum!`]
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use clap::{App, Arg};
+ /// # use std::ascii::AsciiExt;
+ /// let m = App::new("pv")
+ /// .arg(Arg::with_name("option")
+ /// .long("--option")
+ /// .takes_value(true)
+ /// .possible_value("test123")
+ /// .case_insensitive(true))
+ /// .get_matches_from(vec![
+ /// "pv", "--option", "TeSt123",
+ /// ]);
+ ///
+ /// assert!(m.value_of("option").unwrap().eq_ignore_ascii_case("test123"));
+ /// ```
+ ///
+ /// This setting also works when multiple values can be defined:
+ ///
+ /// ```rust
+ /// # use clap::{App, Arg};
+ /// let m = App::new("pv")
+ /// .arg(Arg::with_name("option")
+ /// .short("-o")
+ /// .long("--option")
+ /// .takes_value(true)
+ /// .possible_value("test123")
+ /// .possible_value("test321")
+ /// .multiple(true)
+ /// .case_insensitive(true))
+ /// .get_matches_from(vec![
+ /// "pv", "--option", "TeSt123", "teST123", "tESt321"
+ /// ]);
+ ///
+ /// let matched_vals = m.values_of("option").unwrap().collect::>();
+ /// assert_eq!(&*matched_vals, &["TeSt123", "teST123", "tESt321"]);
+ /// ```
+ /// [`Arg::case_insensitive(true)`]: ./struct.Arg.html#method.possible_values
+ /// [`arg_enum!`]: ./macro.arg_enum.html
+ pub fn case_insensitive(self, ci: bool) -> Self {
+ if ci {
+ self.set(ArgSettings::CaseInsensitive)
+ } else {
+ self.unset(ArgSettings::CaseInsensitive)
+ }
+ }
+
/// Specifies the name of the [`ArgGroup`] the argument belongs to.
///
/// # Examples
@@ -2550,19 +2604,20 @@ impl<'a, 'b> Arg<'a, 'b> {
/// [`Err(String)`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
/// [`Rc`]: https://doc.rust-lang.org/std/rc/struct.Rc.html
pub fn validator(mut self, f: F) -> Self
- where F: Fn(String) -> Result<(), String> + 'static
+ where
+ F: Fn(String) -> Result<(), String> + 'static,
{
self.v.validator = Some(Rc::new(f));
self
}
- /// Works identically to Validator but is intended to be used with values that could
+ /// Works identically to Validator but is intended to be used with values that could
/// contain non UTF-8 formatted strings.
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```rust")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```rust")]
/// # use clap::{App, Arg};
/// # use std::ffi::{OsStr, OsString};
/// # use std::os::unix::ffi::OsStrExt;
@@ -2587,7 +2642,8 @@ impl<'a, 'b> Arg<'a, 'b> {
/// [`Err(String)`]: https://doc.rust-lang.org/std/result/enum.Result.html#variant.Err
/// [`Rc`]: https://doc.rust-lang.org/std/rc/struct.Rc.html
pub fn validator_os(mut self, f: F) -> Self
- where F: Fn(&OsStr) -> Result<(), OsString> + 'static
+ where
+ F: Fn(&OsStr) -> Result<(), OsString> + 'static,
{
self.v.validator_os = Some(Rc::new(f));
self
@@ -2890,9 +2946,11 @@ impl<'a, 'b> Arg<'a, 'b> {
self.unsetb(ArgSettings::ValueDelimiterNotSet);
self.setb(ArgSettings::TakesValue);
self.setb(ArgSettings::UseValueDelimiter);
- self.v.val_delim = Some(d.chars()
- .nth(0)
- .expect("Failed to get value_delimiter from arg"));
+ self.v.val_delim = Some(
+ d.chars()
+ .nth(0)
+ .expect("Failed to get value_delimiter from arg"),
+ );
self
}
@@ -3210,20 +3268,23 @@ impl<'a, 'b> Arg<'a, 'b> {
/// [`Arg::takes_value(true)`]: ./struct.Arg.html#method.takes_value
/// [`Arg::default_value`]: ./struct.Arg.html#method.default_value
pub fn default_value_if(self, arg: &'a str, val: Option<&'b str>, default: &'b str) -> Self {
- self.default_value_if_os(arg,
- val.map(str::as_bytes).map(OsStr::from_bytes),
- OsStr::from_bytes(default.as_bytes()))
+ self.default_value_if_os(
+ arg,
+ val.map(str::as_bytes).map(OsStr::from_bytes),
+ OsStr::from_bytes(default.as_bytes()),
+ )
}
/// Provides a conditional default value in the exact same manner as [`Arg::default_value_if`]
/// only using [`OsStr`]s instead.
/// [`Arg::default_value_if`]: ./struct.Arg.html#method.default_value_if
/// [`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
- pub fn default_value_if_os(mut self,
- arg: &'a str,
- val: Option<&'b OsStr>,
- default: &'b OsStr)
- -> Self {
+ pub fn default_value_if_os(
+ mut self,
+ arg: &'a str,
+ val: Option<&'b OsStr>,
+ default: &'b OsStr,
+ ) -> Self {
self.setb(ArgSettings::TakesValue);
if let Some(ref mut vm) = self.v.default_vals_ifs {
let l = vm.len();
@@ -3322,9 +3383,11 @@ impl<'a, 'b> Arg<'a, 'b> {
/// [`Arg::default_value`]: ./struct.Arg.html#method.default_value
pub fn default_value_ifs(mut self, ifs: &[(&'a str, Option<&'b str>, &'b str)]) -> Self {
for &(arg, val, default) in ifs {
- self = self.default_value_if_os(arg,
- val.map(str::as_bytes).map(OsStr::from_bytes),
- OsStr::from_bytes(default.as_bytes()));
+ self = self.default_value_if_os(
+ arg,
+ val.map(str::as_bytes).map(OsStr::from_bytes),
+ OsStr::from_bytes(default.as_bytes()),
+ );
}
self
}
@@ -3344,7 +3407,7 @@ impl<'a, 'b> Arg<'a, 'b> {
/// Specifies that if the value is not passed in as an argument, that it should be retrieved
/// from the environment, if available. If it is not present in the environment, then default
/// rules will apply.
- ///
+ ///
/// **NOTE:** If the user *does not* use this argument at runtime, [`ArgMatches::occurrences_of`]
/// will return `0` even though the [`ArgMatches::value_of`] will return the default specified.
///
@@ -3352,23 +3415,23 @@ impl<'a, 'b> Arg<'a, 'b> {
/// return `true` if the variable is present in the environemnt . If you wish to determine whether
/// the argument was used at runtime or not, consider [`ArgMatches::occurrences_of`] which will
/// return `0` if the argument was *not* used at runtime.
- ///
+ ///
/// **NOTE:** This implicitly sets [`Arg::takes_value(true)`].
- ///
+ ///
/// **NOTE:** If [`Arg::multiple(true)`] is set then [`Arg::use_delimiter(true)`] should also be
/// set. Otherwise, only a single argument will be returned from the environment variable. The
/// default delimiter is `,` and follows all the other delimiter rules.
- ///
+ ///
/// # Examples
- ///
+ ///
/// In this example, we show the variable coming from the environment:
- ///
+ ///
/// ```rust
/// # use std::env;
/// # use clap::{App, Arg};
///
/// env::set_var("MY_FLAG", "env");
- ///
+ ///
/// let m = App::new("prog")
/// .arg(Arg::with_name("flag")
/// .long("flag")
@@ -3379,15 +3442,15 @@ impl<'a, 'b> Arg<'a, 'b> {
///
/// assert_eq!(m.value_of("flag"), Some("env"));
/// ```
- ///
+ ///
/// In this example, we show the variable coming from an option on the CLI:
- ///
+ ///
/// ```rust
/// # use std::env;
/// # use clap::{App, Arg};
///
/// env::set_var("MY_FLAG", "env");
- ///
+ ///
/// let m = App::new("prog")
/// .arg(Arg::with_name("flag")
/// .long("flag")
@@ -3398,16 +3461,16 @@ impl<'a, 'b> Arg<'a, 'b> {
///
/// assert_eq!(m.value_of("flag"), Some("opt"));
/// ```
- ///
+ ///
/// In this example, we show the variable coming from the environment even with the
/// presence of a default:
- ///
+ ///
/// ```rust
/// # use std::env;
/// # use clap::{App, Arg};
///
/// env::set_var("MY_FLAG", "env");
- ///
+ ///
/// let m = App::new("prog")
/// .arg(Arg::with_name("flag")
/// .long("flag")
@@ -3419,15 +3482,15 @@ impl<'a, 'b> Arg<'a, 'b> {
///
/// assert_eq!(m.value_of("flag"), Some("env"));
/// ```
- ///
+ ///
/// In this example, we show the use of multiple values in a single environment variable:
- ///
+ ///
/// ```rust
/// # use std::env;
/// # use clap::{App, Arg};
///
/// env::set_var("MY_FLAG_MULTI", "env1,env2");
- ///
+ ///
/// let m = App::new("prog")
/// .arg(Arg::with_name("flag")
/// .long("flag")
@@ -3440,9 +3503,7 @@ impl<'a, 'b> Arg<'a, 'b> {
///
/// assert_eq!(m.values_of("flag").unwrap().collect::>(), vec!["env1", "env2"]);
/// ```
- pub fn env(self, name: &'a str) -> Self {
- self.env_os(OsStr::new(name))
- }
+ pub fn env(self, name: &'a str) -> Self { self.env_os(OsStr::new(name)) }
/// Specifies that if the value is not passed in as an argument, that it should be retrieved
/// from the environment if available in the exact same manner as [`Arg::env`] only using
@@ -3606,7 +3667,5 @@ impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for Arg<'a, 'b> {
}
impl<'n, 'e> PartialEq for Arg<'n, 'e> {
- fn eq(&self, other: &Arg<'n, 'e>) -> bool {
- self.b == other.b
- }
+ fn eq(&self, other: &Arg<'n, 'e>) -> bool { self.b == other.b }
}
diff --git a/src/args/arg_builder/base.rs b/src/args/arg_builder/base.rs
index 5990bc08..fef9d8ab 100644
--- a/src/args/arg_builder/base.rs
+++ b/src/args/arg_builder/base.rs
@@ -1,9 +1,9 @@
-
-use args::{ArgSettings, Arg, ArgFlags};
+use args::{Arg, ArgFlags, ArgSettings};
#[derive(Debug, Clone, Default)]
pub struct Base<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
pub name: &'a str,
pub help: Option<&'b str>,
@@ -17,7 +17,12 @@ pub struct Base<'a, 'b>
}
impl<'n, 'e> Base<'n, 'e> {
- pub fn new(name: &'n str) -> Self { Base { name: name, ..Default::default() } }
+ pub fn new(name: &'n str) -> Self {
+ Base {
+ name: name,
+ ..Default::default()
+ }
+ }
pub fn set(&mut self, s: ArgSettings) { self.settings.set(s); }
pub fn unset(&mut self, s: ArgSettings) { self.settings.unset(s); }
@@ -29,7 +34,5 @@ impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for Base<'n, 'e> {
}
impl<'n, 'e> PartialEq for Base<'n, 'e> {
- fn eq(&self, other: &Base<'n, 'e>) -> bool {
- self.name == other.name
- }
-}
\ No newline at end of file
+ fn eq(&self, other: &Base<'n, 'e>) -> bool { self.name == other.name }
+}
diff --git a/src/args/arg_builder/switched.rs b/src/args/arg_builder/switched.rs
index e42586c2..224b2f2b 100644
--- a/src/args/arg_builder/switched.rs
+++ b/src/args/arg_builder/switched.rs
@@ -1,4 +1,3 @@
-
use Arg;
#[derive(Debug)]
diff --git a/src/args/arg_matcher.rs b/src/args/arg_matcher.rs
index 967516c5..4e76802e 100644
--- a/src/args/arg_matcher.rs
+++ b/src/args/arg_matcher.rs
@@ -21,16 +21,19 @@ impl<'a> Default for ArgMatcher<'a> {
impl<'a> ArgMatcher<'a> {
pub fn new() -> Self { ArgMatcher::default() }
- pub fn propagate_globals(&mut self, global_arg_vec : &[&'a str]) {
- debugln!("ArgMatcher::get_global_values: global_arg_vec={:?}", global_arg_vec);
+ pub fn propagate_globals(&mut self, global_arg_vec: &[&'a str]) {
+ debugln!(
+ "ArgMatcher::get_global_values: global_arg_vec={:?}",
+ global_arg_vec
+ );
let mut vals_map = HashMap::new();
self.fill_in_global_values(global_arg_vec, &mut vals_map);
}
fn fill_in_global_values(
- &mut self,
- global_arg_vec: &[&'a str],
- vals_map: &mut HashMap<&'a str, MatchedArg>
+ &mut self,
+ global_arg_vec: &[&'a str],
+ vals_map: &mut HashMap<&'a str, MatchedArg>,
) {
for global_arg in global_arg_vec {
if let Some(ma) = self.get(global_arg) {
@@ -120,7 +123,8 @@ impl<'a> ArgMatcher<'a> {
}
pub fn needs_more_vals<'b, A>(&self, o: &A) -> bool
- where A: AnyArg<'a, 'b>
+ where
+ A: AnyArg<'a, 'b>,
{
debugln!("ArgMatcher::needs_more_vals: o={}", o.name());
if let Some(ma) = self.get(o.name()) {
diff --git a/src/args/arg_matches.rs b/src/args/arg_matches.rs
index 14a19045..770067a3 100644
--- a/src/args/arg_matches.rs
+++ b/src/args/arg_matches.rs
@@ -59,12 +59,9 @@ use args::SubCommand;
/// [`App::get_matches`]: ./struct.App.html#method.get_matches
#[derive(Debug, Clone)]
pub struct ArgMatches<'a> {
- #[doc(hidden)]
- pub args: HashMap<&'a str, MatchedArg>,
- #[doc(hidden)]
- pub subcommand: Option>>,
- #[doc(hidden)]
- pub usage: Option,
+ #[doc(hidden)] pub args: HashMap<&'a str, MatchedArg>,
+ #[doc(hidden)] pub subcommand: Option>>,
+ #[doc(hidden)] pub usage: Option,
}
impl<'a> Default for ArgMatches<'a> {
@@ -79,7 +76,11 @@ impl<'a> Default for ArgMatches<'a> {
impl<'a> ArgMatches<'a> {
#[doc(hidden)]
- pub fn new() -> Self { ArgMatches { ..Default::default() } }
+ pub fn new() -> Self {
+ ArgMatches {
+ ..Default::default()
+ }
+ }
/// Gets the value of a specific [option] or [positional] argument (i.e. an argument that takes
/// an additional value at runtime). If the option wasn't present at runtime
@@ -126,8 +127,8 @@ impl<'a> ArgMatches<'a> {
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
@@ -161,8 +162,8 @@ impl<'a> ArgMatches<'a> {
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
@@ -211,7 +212,9 @@ impl<'a> ArgMatches<'a> {
if let Some(arg) = self.args.get(name.as_ref()) {
fn to_str_slice(o: &OsString) -> &str { o.to_str().expect(INVALID_UTF8) }
let to_str_slice: fn(&OsString) -> &str = to_str_slice; // coerce to fn pointer
- return Some(Values { iter: arg.vals.iter().map(to_str_slice) });
+ return Some(Values {
+ iter: arg.vals.iter().map(to_str_slice),
+ });
}
None
}
@@ -222,8 +225,8 @@ impl<'a> ArgMatches<'a> {
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::OsStringExt;
@@ -242,10 +245,12 @@ impl<'a> ArgMatches<'a> {
/// ```
pub fn values_of_lossy>(&'a self, name: S) -> Option> {
if let Some(arg) = self.args.get(name.as_ref()) {
- return Some(arg.vals
- .iter()
- .map(|v| v.to_string_lossy().into_owned())
- .collect());
+ return Some(
+ arg.vals
+ .iter()
+ .map(|v| v.to_string_lossy().into_owned())
+ .collect(),
+ );
}
None
}
@@ -258,8 +263,8 @@ impl<'a> ArgMatches<'a> {
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// use std::ffi::{OsStr,OsString};
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
@@ -285,7 +290,9 @@ impl<'a> ArgMatches<'a> {
fn to_str_slice(o: &OsString) -> &OsStr { &*o }
let to_str_slice: fn(&'a OsString) -> &'a OsStr = to_str_slice; // coerce to fn pointer
if let Some(arg) = self.args.get(name.as_ref()) {
- return Some(OsValues { iter: arg.vals.iter().map(to_str_slice) });
+ return Some(OsValues {
+ iter: arg.vals.iter().map(to_str_slice),
+ });
}
None
}
@@ -507,7 +514,9 @@ impl<'a> ArgMatches<'a> {
/// [`ArgMatches::subcommand_matches`]: ./struct.ArgMatches.html#method.subcommand_matches
/// [`ArgMatches::subcommand_name`]: ./struct.ArgMatches.html#method.subcommand_name
pub fn subcommand(&self) -> (&str, Option<&ArgMatches<'a>>) {
- self.subcommand.as_ref().map_or(("", None), |sc| (&sc.name[..], Some(&sc.matches)))
+ self.subcommand
+ .as_ref()
+ .map_or(("", None), |sc| (&sc.name[..], Some(&sc.matches)))
}
/// Returns a string slice of the usage statement for the [`App`] or [`SubCommand`]
@@ -573,7 +582,9 @@ impl<'a> Default for Values<'a> {
static EMPTY: [OsString; 0] = [];
// This is never called because the iterator is empty:
fn to_str_slice(_: &OsString) -> &str { unreachable!() };
- Values { iter: EMPTY[..].iter().map(to_str_slice) }
+ Values {
+ iter: EMPTY[..].iter().map(to_str_slice),
+ }
}
}
@@ -596,8 +607,8 @@ fn test_default_values_with_shorter_lifetime() {
///
/// # Examples
///
-#[cfg_attr(not(unix), doc=" ```ignore")]
-#[cfg_attr( unix , doc=" ```")]
+#[cfg_attr(not(unix), doc = " ```ignore")]
+#[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg};
/// use std::ffi::OsString;
/// use std::os::unix::ffi::{OsStrExt,OsStringExt};
@@ -634,7 +645,9 @@ impl<'a> Default for OsValues<'a> {
static EMPTY: [OsString; 0] = [];
// This is never called because the iterator is empty:
fn to_str_slice(_: &OsString) -> &OsStr { unreachable!() };
- OsValues { iter: EMPTY[..].iter().map(to_str_slice) }
+ OsValues {
+ iter: EMPTY[..].iter().map(to_str_slice),
+ }
}
}
diff --git a/src/args/group.rs b/src/args/group.rs
index 1d555aba..e082b69f 100644
--- a/src/args/group.rs
+++ b/src/args/group.rs
@@ -79,18 +79,12 @@ use yaml_rust::Yaml;
/// [requirement]: ./struct.Arg.html#method.requires
#[derive(Default)]
pub struct ArgGroup<'a> {
- #[doc(hidden)]
- pub name: &'a str,
- #[doc(hidden)]
- pub args: Vec<&'a str>,
- #[doc(hidden)]
- pub required: bool,
- #[doc(hidden)]
- pub requires: Option>,
- #[doc(hidden)]
- pub conflicts: Option>,
- #[doc(hidden)]
- pub multiple: bool,
+ #[doc(hidden)] pub name: &'a str,
+ #[doc(hidden)] pub args: Vec<&'a str>,
+ #[doc(hidden)] pub required: bool,
+ #[doc(hidden)] pub requires: Option>,
+ #[doc(hidden)] pub conflicts: Option>,
+ #[doc(hidden)] pub multiple: bool,
}
impl<'a> ArgGroup<'a> {
@@ -154,9 +148,11 @@ impl<'a> ArgGroup<'a> {
/// [argument]: ./struct.Arg.html
#[cfg_attr(feature = "lints", allow(should_assert_eq))]
pub fn arg(mut self, n: &'a str) -> Self {
- assert!(self.name != n,
- "ArgGroup '{}' can not have same name as arg inside it",
- &*self.name);
+ assert!(
+ self.name != n,
+ "ArgGroup '{}' can not have same name as arg inside it",
+ &*self.name
+ );
self.args.push(n);
self
}
@@ -426,19 +422,21 @@ impl<'a> ArgGroup<'a> {
impl<'a> Debug for ArgGroup<'a> {
fn fmt(&self, f: &mut Formatter) -> Result {
- write!(f,
- "{{\n\
- \tname: {:?},\n\
- \targs: {:?},\n\
- \trequired: {:?},\n\
- \trequires: {:?},\n\
- \tconflicts: {:?},\n\
- }}",
- self.name,
- self.args,
- self.required,
- self.requires,
- self.conflicts)
+ write!(
+ f,
+ "{{\n\
+ \tname: {:?},\n\
+ \targs: {:?},\n\
+ \trequired: {:?},\n\
+ \trequires: {:?},\n\
+ \tconflicts: {:?},\n\
+ }}",
+ self.name,
+ self.args,
+ self.required,
+ self.requires,
+ self.conflicts
+ )
}
}
@@ -462,7 +460,9 @@ impl<'a> From<&'a BTreeMap> for ArgGroup<'a> {
let mut a = ArgGroup::default();
let group_settings = if b.len() == 1 {
let name_yml = b.keys().nth(0).expect("failed to get name");
- let name_str = name_yml.as_str().expect("failed to convert arg YAML name to str");
+ let name_str = name_yml
+ .as_str()
+ .expect("failed to convert arg YAML name to str");
a.name = name_str;
b.get(name_yml)
.expect("failed to get name_str")
@@ -491,12 +491,12 @@ impl<'a> From<&'a BTreeMap> for ArgGroup<'a> {
}
a
}
- s => {
- panic!("Unknown ArgGroup setting '{}' in YAML file for \
- ArgGroup '{}'",
- s,
- a.name)
- }
+ s => panic!(
+ "Unknown ArgGroup setting '{}' in YAML file for \
+ ArgGroup '{}'",
+ s,
+ a.name
+ ),
}
}
@@ -551,17 +551,19 @@ mod test {
let reqs = vec!["r1", "r2", "r3", "r4"];
let confs = vec!["c1", "c2", "c3", "c4"];
- let debug_str = format!("{{\n\
- \tname: \"test\",\n\
- \targs: {:?},\n\
- \trequired: {:?},\n\
- \trequires: {:?},\n\
- \tconflicts: {:?},\n\
- }}",
- args,
- true,
- Some(reqs),
- Some(confs));
+ let debug_str = format!(
+ "{{\n\
+ \tname: \"test\",\n\
+ \targs: {:?},\n\
+ \trequired: {:?},\n\
+ \trequires: {:?},\n\
+ \tconflicts: {:?},\n\
+ }}",
+ args,
+ true,
+ Some(reqs),
+ Some(confs)
+ );
assert_eq!(&*format!("{:?}", g), &*debug_str);
}
@@ -589,10 +591,9 @@ mod test {
assert_eq!(g2.conflicts, Some(confs));
}
- #[cfg(feature="yaml")]
+ #[cfg(feature = "yaml")]
#[cfg_attr(feature = "yaml", test)]
fn test_yaml() {
-
let g_yaml = "name: test
args:
- a1
diff --git a/src/args/matched_arg.rs b/src/args/matched_arg.rs
index 9a73af9d..4847718c 100644
--- a/src/args/matched_arg.rs
+++ b/src/args/matched_arg.rs
@@ -4,10 +4,8 @@ use std::ffi::OsString;
#[doc(hidden)]
#[derive(Debug, Clone)]
pub struct MatchedArg {
- #[doc(hidden)]
- pub occurs: u64,
- #[doc(hidden)]
- pub vals: Vec,
+ #[doc(hidden)] pub occurs: u64,
+ #[doc(hidden)] pub vals: Vec,
}
impl Default for MatchedArg {
diff --git a/src/args/mod.rs b/src/args/mod.rs
index 5c87e1be..21f9b850 100644
--- a/src/args/mod.rs
+++ b/src/args/mod.rs
@@ -1,8 +1,8 @@
pub use self::any_arg::{AnyArg, DispOrder};
pub use self::arg::Arg;
-pub use self::arg_builder::{Base, Switched, Valued, FlagBuilder, OptBuilder, PosBuilder};
+pub use self::arg_builder::{Base, FlagBuilder, OptBuilder, PosBuilder, Switched, Valued};
pub use self::arg_matcher::ArgMatcher;
-pub use self::arg_matches::{Values, OsValues, ArgMatches};
+pub use self::arg_matches::{ArgMatches, OsValues, Values};
pub use self::group::ArgGroup;
pub use self::matched_arg::MatchedArg;
pub use self::settings::{ArgFlags, ArgSettings};
diff --git a/src/args/settings.rs b/src/args/settings.rs
index 65bae7e2..d7d065fb 100644
--- a/src/args/settings.rs
+++ b/src/args/settings.rs
@@ -1,10 +1,10 @@
// Std
-#[allow(unused_imports)]
+#[allow(unused_imports)]
use std::ascii::AsciiExt;
use std::str::FromStr;
bitflags! {
- struct Flags: u16 {
+ struct Flags: u32 {
const REQUIRED = 1;
const MULTIPLE = 1 << 1;
const EMPTY_VALS = 1 << 2;
@@ -21,6 +21,7 @@ bitflags! {
const REQUIRE_EQUALS = 1 << 13;
const LAST = 1 << 14;
const HIDE_DEFAULT_VAL = 1 << 15;
+ const CASE_INSENSITIVE = 1 << 16;
}
}
@@ -47,6 +48,7 @@ impl ArgFlags {
AllowLeadingHyphen => Flags::ALLOW_TAC_VALS,
RequireEquals => Flags::REQUIRE_EQUALS,
Last => Flags::LAST,
+ CaseInsensitive => Flags::CASE_INSENSITIVE,
HideDefaultValue => Flags::HIDE_DEFAULT_VAL
}
}
@@ -92,10 +94,10 @@ pub enum ArgSettings {
Last,
/// Hides the default value from the help string
HideDefaultValue,
- #[doc(hidden)]
- RequiredUnlessAll,
- #[doc(hidden)]
- ValueDelimiterNotSet,
+ /// Makes `Arg::possible_values` case insensitive
+ CaseInsensitive,
+ #[doc(hidden)] RequiredUnlessAll,
+ #[doc(hidden)] ValueDelimiterNotSet,
}
impl FromStr for ArgSettings {
@@ -118,6 +120,7 @@ impl FromStr for ArgSettings {
"requireequals" => Ok(ArgSettings::RequireEquals),
"last" => Ok(ArgSettings::Last),
"hidedefaultvalue" => Ok(ArgSettings::HideDefaultValue),
+ "caseinsensitive" => Ok(ArgSettings::CaseInsensitive),
_ => Err("unknown ArgSetting, cannot convert from str".to_owned()),
}
}
@@ -129,38 +132,71 @@ mod test {
#[test]
fn arg_settings_fromstr() {
- assert_eq!("allowleadinghyphen".parse::().unwrap(),
- ArgSettings::AllowLeadingHyphen);
- assert_eq!("emptyvalues".parse::().unwrap(),
- ArgSettings::EmptyValues);
- assert_eq!("global".parse::().unwrap(),
- ArgSettings::Global);
- assert_eq!("hidepossiblevalues".parse::().unwrap(),
- ArgSettings::HidePossibleValues);
- assert_eq!("hidden".parse::().unwrap(),
- ArgSettings::Hidden);
- assert_eq!("multiple".parse::().unwrap(),
- ArgSettings::Multiple);
- assert_eq!("nextlinehelp".parse::().unwrap(),
- ArgSettings::NextLineHelp);
- assert_eq!("requiredunlessall".parse::().unwrap(),
- ArgSettings::RequiredUnlessAll);
- assert_eq!("requiredelimiter".parse::().unwrap(),
- ArgSettings::RequireDelimiter);
- assert_eq!("required".parse::().unwrap(),
- ArgSettings::Required);
- assert_eq!("takesvalue".parse::().unwrap(),
- ArgSettings::TakesValue);
- assert_eq!("usevaluedelimiter".parse::().unwrap(),
- ArgSettings::UseValueDelimiter);
- assert_eq!("valuedelimiternotset".parse::().unwrap(),
- ArgSettings::ValueDelimiterNotSet);
- assert_eq!("requireequals".parse::().unwrap(),
- ArgSettings::RequireEquals);
- assert_eq!("last".parse::().unwrap(),
- ArgSettings::Last);
- assert_eq!("hidedefaultvalue".parse::().unwrap(),
- ArgSettings::HideDefaultValue);
+ assert_eq!(
+ "allowleadinghyphen".parse::().unwrap(),
+ ArgSettings::AllowLeadingHyphen
+ );
+ assert_eq!(
+ "emptyvalues".parse::().unwrap(),
+ ArgSettings::EmptyValues
+ );
+ assert_eq!(
+ "global".parse::().unwrap(),
+ ArgSettings::Global
+ );
+ assert_eq!(
+ "hidepossiblevalues".parse::().unwrap(),
+ ArgSettings::HidePossibleValues
+ );
+ assert_eq!(
+ "hidden".parse::().unwrap(),
+ ArgSettings::Hidden
+ );
+ assert_eq!(
+ "multiple".parse::().unwrap(),
+ ArgSettings::Multiple
+ );
+ assert_eq!(
+ "nextlinehelp".parse::().unwrap(),
+ ArgSettings::NextLineHelp
+ );
+ assert_eq!(
+ "requiredunlessall".parse::().unwrap(),
+ ArgSettings::RequiredUnlessAll
+ );
+ assert_eq!(
+ "requiredelimiter".parse::().unwrap(),
+ ArgSettings::RequireDelimiter
+ );
+ assert_eq!(
+ "required".parse::().unwrap(),
+ ArgSettings::Required
+ );
+ assert_eq!(
+ "takesvalue".parse::().unwrap(),
+ ArgSettings::TakesValue
+ );
+ assert_eq!(
+ "usevaluedelimiter".parse::().unwrap(),
+ ArgSettings::UseValueDelimiter
+ );
+ assert_eq!(
+ "valuedelimiternotset".parse::().unwrap(),
+ ArgSettings::ValueDelimiterNotSet
+ );
+ assert_eq!(
+ "requireequals".parse::().unwrap(),
+ ArgSettings::RequireEquals
+ );
+ assert_eq!("last".parse::().unwrap(), ArgSettings::Last);
+ assert_eq!(
+ "hidedefaultvalue".parse::().unwrap(),
+ ArgSettings::HideDefaultValue
+ );
+ assert_eq!(
+ "caseinsensitive".parse::().unwrap(),
+ ArgSettings::CaseInsensitive
+ );
assert!("hahahaha".parse::().is_err());
}
}
diff --git a/src/args/subcommand.rs b/src/args/subcommand.rs
index 5154c411..eebbf827 100644
--- a/src/args/subcommand.rs
+++ b/src/args/subcommand.rs
@@ -29,10 +29,8 @@ use ArgMatches;
/// [arguments]: ./struct.Arg.html
#[derive(Debug, Clone)]
pub struct SubCommand<'a> {
- #[doc(hidden)]
- pub name: String,
- #[doc(hidden)]
- pub matches: ArgMatches<'a>,
+ #[doc(hidden)] pub name: String,
+ #[doc(hidden)] pub matches: ArgMatches<'a>,
}
impl<'a> SubCommand<'a> {
diff --git a/src/completions/bash.rs b/src/completions/bash.rs
index a5333828..983b250b 100644
--- a/src/completions/bash.rs
+++ b/src/completions/bash.rs
@@ -7,7 +7,8 @@ use args::{ArgSettings, OptBuilder};
use completions;
pub struct BashGen<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
p: &'b Parser<'a, 'b>,
}
@@ -16,9 +17,10 @@ impl<'a, 'b> BashGen<'a, 'b> {
pub fn new(p: &'b Parser<'a, 'b>) -> Self { BashGen { p: p } }
pub fn generate_to(&self, buf: &mut W) {
-
- w!(buf,
- format!("_{name}() {{
+ w!(
+ buf,
+ format!(
+ "_{name}() {{
local i cur prev opts cmds
COMPREPLY=()
cur=\"${{COMP_WORDS[COMP_CWORD]}}\"
@@ -60,13 +62,14 @@ impl<'a, 'b> BashGen<'a, 'b> {
complete -F _{name} -o bashdefault -o default {name}
",
- name = self.p.meta.bin_name.as_ref().unwrap(),
- name_opts = self.all_options_for_path(self.p.meta.bin_name.as_ref().unwrap()),
- name_opts_details =
- self.option_details_for_path(self.p.meta.bin_name.as_ref().unwrap()),
- subcmds = self.all_subcommands(),
- subcmd_details = self.subcommand_details())
- .as_bytes());
+ name = self.p.meta.bin_name.as_ref().unwrap(),
+ name_opts = self.all_options_for_path(self.p.meta.bin_name.as_ref().unwrap()),
+ name_opts_details =
+ self.option_details_for_path(self.p.meta.bin_name.as_ref().unwrap()),
+ subcmds = self.all_subcommands(),
+ subcmd_details = self.subcommand_details()
+ ).as_bytes()
+ );
}
fn all_subcommands(&self) -> String {
@@ -75,12 +78,14 @@ complete -F _{name} -o bashdefault -o default {name}
let scs = completions::all_subcommand_names(self.p);
for sc in &scs {
- subcmds = format!("{}
+ subcmds = format!(
+ "{}
{name})
cmd+=\"__{name}\"
;;",
- subcmds,
- name = sc.replace("-", "__"));
+ subcmds,
+ name = sc.replace("-", "__")
+ );
}
subcmds
@@ -94,7 +99,8 @@ complete -F _{name} -o bashdefault -o default {name}
scs.dedup();
for sc in &scs {
- subcmd_dets = format!("{}
+ subcmd_dets = format!(
+ "{}
{subcmd})
opts=\"{sc_opts}\"
if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then
@@ -110,11 +116,12 @@ complete -F _{name} -o bashdefault -o default {name}
COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) )
return 0
;;",
- subcmd_dets,
- subcmd = sc.replace("-", "__"),
- sc_opts = self.all_options_for_path(&*sc),
- level = sc.split("__").map(|_| 1).fold(0, |acc, n| acc + n),
- opts_details = self.option_details_for_path(&*sc));
+ subcmd_dets,
+ subcmd = sc.replace("-", "__"),
+ sc_opts = self.all_options_for_path(&*sc),
+ level = sc.split("__").map(|_| 1).fold(0, |acc, n| acc + n),
+ opts_details = self.option_details_for_path(&*sc)
+ );
}
subcmd_dets
@@ -130,24 +137,28 @@ complete -F _{name} -o bashdefault -o default {name}
let mut opts = String::new();
for o in p.opts() {
if let Some(l) = o.s.long {
- opts = format!("{}
+ opts = format!(
+ "{}
--{})
COMPREPLY=({})
return 0
;;",
- opts,
- l,
- self.vals_for(o));
+ opts,
+ l,
+ self.vals_for(o)
+ );
}
if let Some(s) = o.s.short {
- opts = format!("{}
+ opts = format!(
+ "{}
-{})
COMPREPLY=({})
return 0
;;",
- opts,
- s,
- self.vals_for(o));
+ opts,
+ s,
+ self.vals_for(o)
+ );
}
}
opts
@@ -164,10 +175,12 @@ complete -F _{name} -o bashdefault -o default {name}
} else if let Some(vec) = o.val_names() {
let mut it = vec.iter().peekable();
while let Some((_, val)) = it.next() {
- ret = format!("{}<{}>{}",
- ret,
- val,
- if it.peek().is_some() { " " } else { "" });
+ ret = format!(
+ "{}<{}>{}",
+ ret,
+ val,
+ if it.peek().is_some() { " " } else { "" }
+ );
}
let num = vec.len();
if o.is_set(ArgSettings::Multiple) && num == 1 {
@@ -176,10 +189,12 @@ complete -F _{name} -o bashdefault -o default {name}
} else if let Some(num) = o.num_vals() {
let mut it = (0..num).peekable();
while let Some(_) = it.next() {
- ret = format!("{}<{}>{}",
- ret,
- o.name(),
- if it.peek().is_some() { " " } else { "" });
+ ret = format!(
+ "{}<{}>{}",
+ ret,
+ o.name(),
+ if it.peek().is_some() { " " } else { "" }
+ );
}
if o.is_set(ArgSettings::Multiple) && num == 1 {
ret = format!("{}...", ret);
@@ -203,26 +218,35 @@ complete -F _{name} -o bashdefault -o default {name}
p = &find_subcmd!(p, sc).unwrap().p;
}
let mut opts = shorts!(p).fold(String::new(), |acc, s| format!("{} -{}", acc, s));
- opts = format!("{} {}",
- opts,
- longs!(p).fold(String::new(), |acc, l| format!("{} --{}", acc, l)));
- opts = format!("{} {}",
- opts,
- p.positionals
- .values()
- .fold(String::new(), |acc, p| format!("{} {}", acc, p)));
- opts = format!("{} {}",
- opts,
- p.subcommands
- .iter()
- .fold(String::new(), |acc, s| format!("{} {}", acc, s.p.meta.name)));
+ opts = format!(
+ "{} {}",
+ opts,
+ longs!(p).fold(String::new(), |acc, l| format!("{} --{}", acc, l))
+ );
+ opts = format!(
+ "{} {}",
+ opts,
+ p.positionals
+ .values()
+ .fold(String::new(), |acc, p| format!("{} {}", acc, p))
+ );
+ opts = format!(
+ "{} {}",
+ opts,
+ p.subcommands
+ .iter()
+ .fold(String::new(), |acc, s| format!("{} {}", acc, s.p.meta.name))
+ );
for sc in &p.subcommands {
if let Some(ref aliases) = sc.p.meta.aliases {
- opts = format!("{} {}",
- opts,
- aliases.iter()
- .map(|&(n, _)| n)
- .fold(String::new(), |acc, a| format!("{} {}", acc, a)));
+ opts = format!(
+ "{} {}",
+ opts,
+ aliases
+ .iter()
+ .map(|&(n, _)| n)
+ .fold(String::new(), |acc, a| format!("{} {}", acc, a))
+ );
}
}
opts
diff --git a/src/completions/fish.rs b/src/completions/fish.rs
index 96e8cc24..841c39b3 100644
--- a/src/completions/fish.rs
+++ b/src/completions/fish.rs
@@ -1,4 +1,3 @@
-
// Std
use std::io::Write;
@@ -6,7 +5,8 @@ use std::io::Write;
use app::parser::Parser;
pub struct FishGen<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
p: &'b Parser<'a, 'b>,
}
@@ -31,8 +31,7 @@ impl<'a, 'b> FishGen<'a, 'b> {
return 1
end
-"#
- .to_string();
+"#.to_string();
let mut buffer = detect_subcommand_function;
gen_fish_inner(command, self, &command.to_string(), &mut buffer);
@@ -41,9 +40,7 @@ end
}
// Escape string inside single quotes
-fn escape_string(string: &str) -> String {
- string.replace("\\", "\\\\").replace("'", "\\'")
-}
+fn escape_string(string: &str) -> String { string.replace("\\", "\\\\").replace("'", "\\'") }
fn gen_fish_inner(root_command: &str, comp_gen: &FishGen, parent_cmds: &str, buffer: &mut String) {
debugln!("FishGen::gen_fish_inner;");
@@ -59,9 +56,11 @@ fn gen_fish_inner(root_command: &str, comp_gen: &FishGen, parent_cmds: &str, buf
// -f # don't use file completion
// -n "__fish_using_command myprog subcmd1" # complete for command "myprog subcmd1"
- let basic_template = format!("complete -c {} -n \"__fish_using_command {}\"",
- root_command,
- parent_cmds);
+ let basic_template = format!(
+ "complete -c {} -n \"__fish_using_command {}\"",
+ root_command,
+ parent_cmds
+ );
for option in comp_gen.p.opts() {
let mut template = basic_template.clone();
diff --git a/src/completions/macros.rs b/src/completions/macros.rs
index a4ffce4b..653c72c4 100644
--- a/src/completions/macros.rs
+++ b/src/completions/macros.rs
@@ -1,4 +1,3 @@
-
macro_rules! w {
($buf:expr, $to_w:expr) => {
match $buf.write_all($to_w) {
@@ -20,7 +19,7 @@ macro_rules! get_zsh_arg_conflicts {
if let Some(l) = arg.long() {
v.push(format!("--{}", l));
}
- }
+ }
v.join(" ")
} else {
String::new()
diff --git a/src/completions/mod.rs b/src/completions/mod.rs
index 6d067882..026b4493 100644
--- a/src/completions/mod.rs
+++ b/src/completions/mod.rs
@@ -18,7 +18,8 @@ use self::powershell::PowerShellGen;
pub use self::shell::Shell;
pub struct ComplGen<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
p: &'b Parser<'a, 'b>,
}
@@ -44,7 +45,10 @@ impl<'a, 'b> ComplGen<'a, 'b> {
// aliasing.
pub fn all_subcommand_names(p: &Parser) -> Vec {
debugln!("all_subcommand_names;");
- let mut subcmds: Vec<_> = subcommands_of(p).iter().map(|&(ref n, _)| n.clone()).collect();
+ let mut subcmds: Vec<_> = subcommands_of(p)
+ .iter()
+ .map(|&(ref n, _)| n.clone())
+ .collect();
for sc_v in p.subcommands.iter().map(|s| all_subcommand_names(&s.p)) {
subcmds.extend(sc_v);
}
@@ -75,14 +79,24 @@ pub fn all_subcommands(p: &Parser) -> Vec<(String, String)> {
// Also note, aliases are treated as their own subcommands but duplicates of whatever they're
// aliasing.
pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
- debugln!("subcommands_of: name={}, bin_name={}",
- p.meta.name,
- p.meta.bin_name.as_ref().unwrap());
+ debugln!(
+ "subcommands_of: name={}, bin_name={}",
+ p.meta.name,
+ p.meta.bin_name.as_ref().unwrap()
+ );
let mut subcmds = vec![];
- debugln!("subcommands_of: Has subcommands...{:?}", p.has_subcommands());
+ debugln!(
+ "subcommands_of: Has subcommands...{:?}",
+ p.has_subcommands()
+ );
if !p.has_subcommands() {
- let mut ret = vec![(p.meta.name.clone(), p.meta.bin_name.as_ref().unwrap().clone())];
+ let mut ret = vec![
+ (
+ p.meta.name.clone(),
+ p.meta.bin_name.as_ref().unwrap().clone(),
+ ),
+ ];
debugln!("subcommands_of: Looking for aliases...");
if let Some(ref aliases) = p.meta.aliases {
for &(n, _) in aliases {
@@ -98,9 +112,11 @@ pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
return ret;
}
for sc in &p.subcommands {
- debugln!("subcommands_of:iter: name={}, bin_name={}",
- sc.p.meta.name,
- sc.p.meta.bin_name.as_ref().unwrap());
+ debugln!(
+ "subcommands_of:iter: name={}, bin_name={}",
+ sc.p.meta.name,
+ sc.p.meta.bin_name.as_ref().unwrap()
+ );
debugln!("subcommands_of:iter: Looking for aliases...");
if let Some(ref aliases) = sc.p.meta.aliases {
@@ -114,7 +130,10 @@ pub fn subcommands_of(p: &Parser) -> Vec<(String, String)> {
subcmds.push((n.to_owned(), als_bin_name.join(" ")));
}
}
- subcmds.push((sc.p.meta.name.clone(), sc.p.meta.bin_name.as_ref().unwrap().clone()));
+ subcmds.push((
+ sc.p.meta.name.clone(),
+ sc.p.meta.bin_name.as_ref().unwrap().clone(),
+ ));
}
subcmds
}
@@ -138,7 +157,13 @@ pub fn get_all_subcommand_paths(p: &Parser, first: bool) -> Vec {
}
for sc in &p.subcommands {
let name = &*sc.p.meta.name;
- let path = sc.p.meta.bin_name.as_ref().unwrap().clone().replace(" ", "__");
+ let path = sc.p
+ .meta
+ .bin_name
+ .as_ref()
+ .unwrap()
+ .clone()
+ .replace(" ", "__");
subcmds.push(path.clone());
if let Some(ref aliases) = sc.p.meta.aliases {
for &(n, _) in aliases {
@@ -146,7 +171,10 @@ pub fn get_all_subcommand_paths(p: &Parser, first: bool) -> Vec {
}
}
}
- for sc_v in p.subcommands.iter().map(|s| get_all_subcommand_paths(&s.p, false)) {
+ for sc_v in p.subcommands
+ .iter()
+ .map(|s| get_all_subcommand_paths(&s.p, false))
+ {
subcmds.extend(sc_v);
}
subcmds
diff --git a/src/completions/powershell.rs b/src/completions/powershell.rs
index 423dd450..19b14969 100644
--- a/src/completions/powershell.rs
+++ b/src/completions/powershell.rs
@@ -1,4 +1,3 @@
-
// Std
use std::io::Write;
@@ -7,7 +6,8 @@ use app::parser::Parser;
use INTERNAL_ERROR_MSG;
pub struct PowerShellGen<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
p: &'b Parser<'a, 'b>,
}
@@ -19,7 +19,8 @@ impl<'a, 'b> PowerShellGen<'a, 'b> {
let bin_name = self.p.meta.bin_name.as_ref().unwrap();
let mut names = vec![];
- let (subcommands_detection_cases, subcommands_cases) = generate_inner(self.p, "", &mut names);
+ let (subcommands_detection_cases, subcommands_cases) =
+ generate_inner(self.p, "", &mut names);
let mut bin_names = vec![bin_name.to_string(), format!("./{0}", bin_name)];
if cfg!(windows) {
@@ -74,23 +75,33 @@ impl<'a, 'b> PowerShellGen<'a, 'b> {
}
}
-fn generate_inner<'a, 'b, 'p>(p: &'p Parser<'a, 'b>, previous_command_name: &str, names: &mut Vec<&'p str>) -> (String, String) {
+fn generate_inner<'a, 'b, 'p>(
+ p: &'p Parser<'a, 'b>,
+ previous_command_name: &str,
+ names: &mut Vec<&'p str>,
+) -> (String, String) {
debugln!("PowerShellGen::generate_inner;");
let command_name = if previous_command_name.is_empty() {
- format!("{}_{}", previous_command_name, &p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG))
+ format!(
+ "{}_{}",
+ previous_command_name,
+ &p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG)
+ )
} else {
format!("{}_{}", previous_command_name, &p.meta.name)
};
let mut subcommands_detection_cases = if !names.contains(&&*p.meta.name) {
names.push(&*p.meta.name);
- format!(r"
+ format!(
+ r"
'{0}' {{
$command += '_{0}'
break
}}
",
- &p.meta.name)
+ &p.meta.name
+ )
} else {
String::new()
};
@@ -106,13 +117,15 @@ fn generate_inner<'a, 'b, 'p>(p: &'p Parser<'a, 'b>, previous_command_name: &str
completions.push_str(&format!("'--{}', ", long));
}
- let mut subcommands_cases = format!(r"
+ let mut subcommands_cases = format!(
+ r"
'{}' {{
$completions = @({})
}}
",
- &command_name,
- completions.trim_right_matches(", "));
+ &command_name,
+ completions.trim_right_matches(", ")
+ );
for subcommand in &p.subcommands {
let (subcommand_subcommands_detection_cases, subcommand_subcommands_cases) =
diff --git a/src/completions/shell.rs b/src/completions/shell.rs
index 67c5bd1c..75b7d360 100644
--- a/src/completions/shell.rs
+++ b/src/completions/shell.rs
@@ -1,4 +1,4 @@
-#[allow(unused_imports)]
+#[allow(unused_imports)]
use std::ascii::AsciiExt;
use std::str::FromStr;
use std::fmt;
@@ -27,7 +27,6 @@ impl FromStr for Shell {
fn from_str(s: &str) -> Result {
match s {
-
"ZSH" | _ if s.eq_ignore_ascii_case("zsh") => Ok(Shell::Zsh),
"FISH" | _ if s.eq_ignore_ascii_case("fish") => Ok(Shell::Fish),
"BASH" | _ if s.eq_ignore_ascii_case("bash") => Ok(Shell::Bash),
diff --git a/src/completions/zsh.rs b/src/completions/zsh.rs
index 7950705e..8fbc1ff6 100644
--- a/src/completions/zsh.rs
+++ b/src/completions/zsh.rs
@@ -1,18 +1,18 @@
-
// Std
use std::io::Write;
-#[allow(unused_imports)]
+#[allow(unused_imports)]
use std::ascii::AsciiExt;
// Internal
use app::App;
use app::parser::Parser;
-use args::{ArgSettings, AnyArg};
+use args::{AnyArg, ArgSettings};
use completions;
use INTERNAL_ERROR_MSG;
pub struct ZshGen<'a, 'b>
- where 'a: 'b
+where
+ 'a: 'b,
{
p: &'b Parser<'a, 'b>,
}
@@ -25,8 +25,10 @@ impl<'a, 'b> ZshGen<'a, 'b> {
pub fn generate_to(&self, buf: &mut W) {
debugln!("ZshGen::generate_to;");
- w!(buf,
- format!("\
+ w!(
+ buf,
+ format!(
+ "\
#compdef {name}
_{name}() {{
@@ -41,11 +43,12 @@ _{name}() {{
{subcommand_details}
_{name} \"$@\"",
- name = self.p.meta.bin_name.as_ref().unwrap(),
- initial_args = get_args_of(self.p),
- subcommands = get_subcommands_of(self.p),
- subcommand_details = subcommand_details(self.p)).as_bytes());
-
+ name = self.p.meta.bin_name.as_ref().unwrap(),
+ initial_args = get_args_of(self.p),
+ subcommands = get_subcommands_of(self.p),
+ subcommand_details = subcommand_details(self.p)
+ ).as_bytes()
+ );
}
}
@@ -79,7 +82,9 @@ _{name} \"$@\"",
fn subcommand_details(p: &Parser) -> String {
debugln!("ZshGen::subcommand_details;");
// First we do ourself
- let mut ret = vec![format!("\
+ let mut ret = vec![
+ format!(
+ "\
(( $+functions[_{bin_name_underscore}_commands] )) ||
_{bin_name_underscore}_commands() {{
local commands; commands=(
@@ -89,7 +94,9 @@ _{bin_name_underscore}_commands() {{
}}",
bin_name_underscore = p.meta.bin_name.as_ref().unwrap().replace(" ", "__"),
bin_name = p.meta.bin_name.as_ref().unwrap(),
- subcommands_and_args = subcommands_and_args_of(p))];
+ subcommands_and_args = subcommands_and_args_of(p)
+ ),
+ ];
// Next we start looping through all the children, grandchildren, etc.
let mut all_subcommands = completions::all_subcommands(p);
@@ -97,7 +104,8 @@ _{bin_name_underscore}_commands() {{
all_subcommands.dedup();
for &(_, ref bin_name) in &all_subcommands {
debugln!("ZshGen::subcommand_details:iter: bin_name={}", bin_name);
- ret.push(format!("\
+ ret.push(format!(
+ "\
(( $+functions[_{bin_name_underscore}_commands] )) ||
_{bin_name_underscore}_commands() {{
local commands; commands=(
@@ -107,7 +115,8 @@ _{bin_name_underscore}_commands() {{
}}",
bin_name_underscore = bin_name.replace(" ", "__"),
bin_name = bin_name,
- subcommands_and_args = subcommands_and_args_of(parser_of(p, bin_name))));
+ subcommands_and_args = subcommands_and_args_of(parser_of(p, bin_name))
+ ));
}
ret.join("\n")
@@ -129,9 +138,16 @@ fn subcommands_and_args_of(p: &Parser) -> String {
let mut ret = vec![];
fn add_sc(sc: &App, n: &str, ret: &mut Vec) {
debugln!("ZshGen::add_sc;");
- let s = format!("\"{name}:{help}\" \\",
- name = n,
- help = sc.p.meta.about.unwrap_or("").replace("[", "\\[").replace("]", "\\]"));
+ let s = format!(
+ "\"{name}:{help}\" \\",
+ name = n,
+ help = sc.p
+ .meta
+ .about
+ .unwrap_or("")
+ .replace("[", "\\[")
+ .replace("]", "\\]")
+ );
if !s.is_empty() {
ret.push(s);
}
@@ -139,7 +155,10 @@ fn subcommands_and_args_of(p: &Parser) -> String {
// First the subcommands
for sc in p.subcommands() {
- debugln!("ZshGen::subcommands_and_args_of:iter: subcommand={}", sc.p.meta.name);
+ debugln!(
+ "ZshGen::subcommands_and_args_of:iter: subcommand={}",
+ sc.p.meta.name
+ );
add_sc(sc, &sc.p.meta.name, &mut ret);
if let Some(ref v) = sc.p.meta.aliases {
for alias in v.iter().filter(|&&(_, vis)| vis).map(|&(n, _)| n) {
@@ -151,9 +170,15 @@ fn subcommands_and_args_of(p: &Parser) -> String {
// Then the positional args
for arg in p.positionals() {
debugln!("ZshGen::subcommands_and_args_of:iter: arg={}", arg.b.name);
- let a = format!("\"{name}:{help}\" \\",
- name = arg.b.name.to_ascii_uppercase(),
- help = arg.b.help.unwrap_or("").replace("[", "\\[").replace("]", "\\]"));
+ let a = format!(
+ "\"{name}:{help}\" \\",
+ name = arg.b.name.to_ascii_uppercase(),
+ help = arg.b
+ .help
+ .unwrap_or("")
+ .replace("[", "\\[")
+ .replace("]", "\\]")
+ );
if !a.is_empty() {
ret.push(a);
@@ -195,7 +220,10 @@ fn subcommands_and_args_of(p: &Parser) -> String {
fn get_subcommands_of(p: &Parser) -> String {
debugln!("get_subcommands_of;");
- debugln!("get_subcommands_of: Has subcommands...{:?}", p.has_subcommands());
+ debugln!(
+ "get_subcommands_of: Has subcommands...{:?}",
+ p.has_subcommands()
+ );
if !p.has_subcommands() {
return String::new();
}
@@ -218,17 +246,18 @@ fn get_subcommands_of(p: &Parser) -> String {
}
format!(
-"case $state in
+ "case $state in
({name})
curcontext=\"${{curcontext%:*:*}}:{name_hyphen}-command-$words[1]:\"
case $line[1] in
{subcommands}
esac
;;
-esac",
+esac",
name = p.meta.name,
name_hyphen = p.meta.bin_name.as_ref().unwrap().replace(" ", "-"),
- subcommands = subcmds.join("\n"))
+ subcommands = subcmds.join("\n")
+ )
}
fn parser_of<'a, 'b>(p: &'b Parser<'a, 'b>, sc: &str) -> &'b Parser<'a, 'b> {
@@ -265,8 +294,10 @@ fn get_args_of(p: &Parser) -> String {
let opts = write_opts_of(p);
let flags = write_flags_of(p);
let sc_or_a = if p.has_subcommands() || p.has_positionals() {
- format!("\"1:: :_{name}_commands\" \\",
- name = p.meta.bin_name.as_ref().unwrap().replace(" ", "__"))
+ format!(
+ "\"1:: :_{name}_commands\" \\",
+ name = p.meta.bin_name.as_ref().unwrap().replace(" ", "__")
+ )
} else {
String::new()
};
@@ -295,7 +326,8 @@ fn get_args_of(p: &Parser) -> String {
// Escape string inside single quotes and brackets
fn escape_string(string: &str) -> String {
- string.replace("\\", "\\\\")
+ string
+ .replace("\\", "\\\\")
.replace("'", "'\\''")
.replace("[", "\\[")
.replace("]", "\\]")
@@ -325,23 +357,27 @@ fn write_opts_of(p: &Parser) -> String {
String::new()
};
if let Some(short) = o.short() {
- let s = format!("'{conflicts}{multiple}-{arg}+[{help}]{possible_values}' \\",
+ let s = format!(
+ "'{conflicts}{multiple}-{arg}+[{help}]{possible_values}' \\",
conflicts = conflicts,
multiple = multiple,
arg = short,
possible_values = pv,
- help = help);
+ help = help
+ );
debugln!("write_opts_of:iter: Wrote...{}", &*s);
ret.push(s);
}
if let Some(long) = o.long() {
- let l = format!("'{conflicts}{multiple}--{arg}+[{help}]{possible_values}' \\",
+ let l = format!(
+ "'{conflicts}{multiple}--{arg}+[{help}]{possible_values}' \\",
conflicts = conflicts,
multiple = multiple,
arg = long,
possible_values = pv,
- help = help);
+ help = help
+ );
debugln!("write_opts_of:iter: Wrote...{}", &*l);
ret.push(l);
@@ -370,22 +406,26 @@ fn write_flags_of(p: &Parser) -> String {
""
};
if let Some(short) = f.short() {
- let s = format!("'{conflicts}{multiple}-{arg}[{help}]' \\",
+ let s = format!(
+ "'{conflicts}{multiple}-{arg}[{help}]' \\",
multiple = multiple,
conflicts = conflicts,
arg = short,
- help = help);
+ help = help
+ );
debugln!("write_flags_of:iter: Wrote...{}", &*s);
ret.push(s);
}
if let Some(long) = f.long() {
- let l = format!("'{conflicts}{multiple}--{arg}[{help}]' \\",
+ let l = format!(
+ "'{conflicts}{multiple}--{arg}[{help}]' \\",
conflicts = conflicts,
multiple = multiple,
arg = long,
- help = help);
+ help = help
+ );
debugln!("write_flags_of:iter: Wrote...{}", &*l);
ret.push(l);
diff --git a/src/errors.rs b/src/errors.rs
index bd1e7d55..c4108a64 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -8,8 +8,8 @@ use std::process;
use std::result::Result as StdResult;
// Internal
-use args::{FlagBuilder, AnyArg};
-use fmt::{Colorizer, ColorizerOption, ColorWhen};
+use args::{AnyArg, FlagBuilder};
+use fmt::{ColorWhen, Colorizer, ColorizerOption};
use suggestions;
/// Short hand for [`Result`] type
@@ -58,8 +58,8 @@ pub enum ErrorKind {
///
/// # Examples
///
- #[cfg_attr(not(feature="suggestions"), doc=" ```no_run")]
- #[cfg_attr( feature="suggestions" , doc=" ```")]
+ #[cfg_attr(not(feature = "suggestions"), doc = " ```no_run")]
+ #[cfg_attr(feature = "suggestions", doc = " ```")]
/// # use clap::{App, Arg, ErrorKind, SubCommand};
/// let result = App::new("prog")
/// .subcommand(SubCommand::with_name("config")
@@ -300,8 +300,8 @@ pub enum ErrorKind {
///
/// # Examples
///
- #[cfg_attr(not(unix), doc=" ```ignore")]
- #[cfg_attr( unix , doc=" ```")]
+ #[cfg_attr(not(unix), doc = " ```ignore")]
+ #[cfg_attr(unix, doc = " ```")]
/// # use clap::{App, Arg, ErrorKind, AppSettings};
/// # use std::os::unix::ffi::OsStringExt;
/// # use std::ffi::OsString;
@@ -384,8 +384,7 @@ impl Error {
/// Should the message be written to `stdout` or not
pub fn use_stderr(&self) -> bool {
match self.kind {
- ErrorKind::HelpDisplayed |
- ErrorKind::VersionDisplayed => false,
+ ErrorKind::HelpDisplayed | ErrorKind::VersionDisplayed => false,
_ => true,
}
}
@@ -405,14 +404,16 @@ impl Error {
pub fn write_to(&self, w: &mut W) -> io::Result<()> { write!(w, "{}", self.message) }
#[doc(hidden)]
- pub fn argument_conflict<'a, 'b, A, O, U>(arg: &A,
- other: Option,
- usage: U,
- color: ColorWhen)
- -> Self
- where A: AnyArg<'a, 'b> + Display,
- O: Into,
- U: Display
+ pub fn argument_conflict<'a, 'b, A, O, U>(
+ arg: &A,
+ other: Option,
+ usage: U,
+ color: ColorWhen,
+ ) -> Self
+ where
+ A: AnyArg<'a, 'b> + Display,
+ O: Into,
+ U: Display,
{
let mut v = vec![arg.name().to_owned()];
let c = Colorizer::new(ColorizerOption {
@@ -420,24 +421,23 @@ impl Error {
when: color,
});
Error {
- message: format!("{} The argument '{}' cannot be used with {}\n\n\
- {}\n\n\
- For more information try {}",
- c.error("error:"),
- c.warning(&*arg.to_string()),
- match other {
- Some(name) => {
- let n = name.into();
- v.push(n.clone());
- c.warning(format!("'{}'", n))
- }
- None => {
- c.none("one or more of the other specified arguments"
- .to_owned())
- }
- },
- usage,
- c.good("--help")),
+ message: format!(
+ "{} The argument '{}' cannot be used with {}\n\n\
+ {}\n\n\
+ For more information try {}",
+ c.error("error:"),
+ c.warning(&*arg.to_string()),
+ match other {
+ Some(name) => {
+ let n = name.into();
+ v.push(n.clone());
+ c.warning(format!("'{}'", n))
+ }
+ None => c.none("one or more of the other specified arguments".to_owned()),
+ },
+ usage,
+ c.good("--help")
+ ),
kind: ErrorKind::ArgumentConflict,
info: Some(v),
}
@@ -445,47 +445,49 @@ impl Error {
#[doc(hidden)]
pub fn empty_value<'a, 'b, A, U>(arg: &A, usage: U, color: ColorWhen) -> Self
- where A: AnyArg<'a, 'b> + Display,
- U: Display
+ where
+ A: AnyArg<'a, 'b> + Display,
+ U: Display,
{
let c = Colorizer::new(ColorizerOption {
use_stderr: true,
when: color,
});
Error {
- message: format!("{} The argument '{}' requires a value but none was supplied\
- \n\n\
- {}\n\n\
- For more information try {}",
- c.error("error:"),
- c.warning(arg.to_string()),
- usage,
- c.good("--help")),
+ message: format!(
+ "{} The argument '{}' requires a value but none was supplied\
+ \n\n\
+ {}\n\n\
+ For more information try {}",
+ c.error("error:"),
+ c.warning(arg.to_string()),
+ usage,
+ c.good("--help")
+ ),
kind: ErrorKind::EmptyValue,
info: Some(vec![arg.name().to_owned()]),
}
}
#[doc(hidden)]
- pub fn invalid_value<'a, 'b, B, G, A, U>(bad_val: B,
- good_vals: &[G],
- arg: &A,
- usage: U,
- color: ColorWhen)
- -> Self
- where B: AsRef,
- G: AsRef + Display,
- A: AnyArg<'a, 'b> + Display,
- U: Display
+ pub fn invalid_value<'a, 'b, B, G, A, U>(
+ bad_val: B,
+ good_vals: &[G],
+ arg: &A,
+ usage: U,
+ color: ColorWhen,
+ ) -> Self
+ where
+ B: AsRef,
+ G: AsRef + Display,
+ A: AnyArg<'a, 'b> + Display,
+ U: Display,
{
let c = Colorizer::new(ColorizerOption {
use_stderr: true,
when: color,
});
- let suffix =
- suggestions::did_you_mean_value_suffix(
- bad_val.as_ref(),
- good_vals.iter());
+ let suffix = suggestions::did_you_mean_value_suffix(bad_val.as_ref(), good_vals.iter());
let mut sorted = vec![];
for v in good_vals {
@@ -495,34 +497,38 @@ impl Error {
sorted.sort();
let valid_values = sorted.join(", ");
Error {
- message: format!("{} '{}' isn't a valid value for '{}'\n\t\
- [values: {}]\n\
- {}\n\n\
- {}\n\n\
- For more information try {}",
- c.error("error:"),
- c.warning(bad_val.as_ref()),
- c.warning(arg.to_string()),
- valid_values,
- suffix.0,
- usage,
- c.good("--help")),
+ message: format!(
+ "{} '{}' isn't a valid value for '{}'\n\t\
+ [values: {}]\n\
+ {}\n\n\
+ {}\n\n\
+ For more information try {}",
+ c.error("error:"),
+ c.warning(bad_val.as_ref()),
+ c.warning(arg.to_string()),
+ valid_values,
+ suffix.0,
+ usage,
+ c.good("--help")
+ ),
kind: ErrorKind::InvalidValue,
info: Some(vec![arg.name().to_owned(), bad_val.as_ref().to_owned()]),
}
}
#[doc(hidden)]
- pub fn invalid_subcommand
(subcmd: S,
- did_you_mean: D,
- name: N,
- usage: U,
- color: ColorWhen)
- -> Self
- where S: Into,
- D: AsRef + Display,
- N: Display,
- U: Display
+ pub fn invalid_subcommand(
+ subcmd: S,
+ did_you_mean: D,
+ name: N,
+ usage: U,
+ color: ColorWhen,
+ ) -> Self
+ where
+ S: Into,
+ D: AsRef + Display,
+ N: Display,
+ U: Display,
{
let s = subcmd.into();
let c = Colorizer::new(ColorizerOption {
@@ -530,20 +536,22 @@ impl Error {
when: color,
});
Error {
- message: format!("{} The subcommand '{}' wasn't recognized\n\t\
- Did you mean '{}'?\n\n\
- If you believe you received this message in error, try \
- re-running with '{} {} {}'\n\n\
- {}\n\n\
- For more information try {}",
- c.error("error:"),
- c.warning(&*s),
- c.good(did_you_mean.as_ref()),
- name,
- c.good("--"),
- &*s,
- usage,
- c.good("--help")),
+ message: format!(
+ "{} The subcommand '{}' wasn't recognized\n\t\
+ Did you mean '{}'?\n\n\
+ If you believe you received this message in error, try \
+ re-running with '{} {} {}'\n\n\
+ {}\n\n\
+ For more information try {}",
+ c.error("error:"),
+ c.warning(&*s),
+ c.good(did_you_mean.as_ref()),
+ name,
+ c.good("--"),
+ &*s,
+ usage,
+ c.good("--help")
+ ),
kind: ErrorKind::InvalidSubcommand,
info: Some(vec![s]),
}
@@ -551,8 +559,9 @@ impl Error {
#[doc(hidden)]
pub fn unrecognized_subcommand(subcmd: S, name: N, color: ColorWhen) -> Self
- where S: Into,
- N: Display
+ where
+ S: Into,
+ N: Display,
{
let s = subcmd.into();
let c = Colorizer::new(ColorizerOption {
@@ -560,15 +569,17 @@ impl Error {
when: color,
});
Error {
- message: format!("{} The subcommand '{}' wasn't recognized\n\n\
- {}\n\t\
- {} help