diff --git a/clap_derive/src/derives/subcommand.rs b/clap_derive/src/derives/subcommand.rs index ba433821cb20..59f83cacea9c 100644 --- a/clap_derive/src/derives/subcommand.rs +++ b/clap_derive/src/derives/subcommand.rs @@ -15,7 +15,8 @@ pub fn derive_subcommand(input: &syn::DeriveInput) -> TokenStream { impl ::clap::Subcommand for #name { fn from_subcommand<'b>( name: &str, - matches: ::std::option::Option<&::clap::ArgMatches>) -> Option { + matches: ::std::option::Option<&::clap::ArgMatches> + ) -> Option { unimplemented!() } diff --git a/src/derive.rs b/src/derive.rs new file mode 100644 index 000000000000..bf333021d626 --- /dev/null +++ b/src/derive.rs @@ -0,0 +1,66 @@ +use crate::{App, ArgMatches, Error}; +use std::ffi::OsString; + +/// This trait is just a convenience on top of FromArgMatches + IntoApp +pub trait Clap: FromArgMatches + IntoApp + Sized { + /// Parse from `std::env::args()`, exit on error + fn parse() -> Self { + let matches = ::into_app().get_matches(); + ::from_arg_matches(&matches) + } + + /// Parse from `std::env::args()`, return Err on error. + fn try_parse() -> Result { + let matches = ::into_app().try_get_matches()?; + Ok(::from_arg_matches(&matches)) + } + + /// Parse from iterator, exit on error + fn parse_from(itr: I) -> Self + where + I: IntoIterator, + // TODO (@CreepySkeleton): discover a way to avoid cloning here + T: Into + Clone, + { + let matches = ::into_app().get_matches_from(itr); + ::from_arg_matches(&matches) + } + + /// Parse from `std::env::args()`, return Err on error. + fn try_parse_from(itr: I) -> Result + where + I: IntoIterator, + // TODO (@CreepySkeleton): discover a way to avoid cloning here + T: Into + Clone, + { + let matches = ::into_app().try_get_matches_from(itr)?; + Ok(::from_arg_matches(&matches)) + } +} + +/// Build an App according to the struct +/// +/// Also serves for flattening +pub trait IntoApp: Sized { + /// @TODO @release @docs + fn into_app<'b>() -> App<'b>; + /// @TODO @release @docs + fn augment_clap<'b>(app: App<'b>) -> App<'b>; +} + +/// Extract values from ArgMatches into the struct. +pub trait FromArgMatches: Sized { + /// @TODO @release @docs + fn from_arg_matches<'b>(matches: &ArgMatches) -> Self; +} + +/// @TODO @release @docs +pub trait Subcommand: Sized { + /// @TODO @release @docs + fn from_subcommand<'b>(name: &str, matches: Option<&ArgMatches>) -> Option; + /// @TODO @release @docs + fn augment_subcommands<'b>(app: App<'b>) -> App<'b>; +} + +/// @TODO @release @docs +pub trait ArgEnum {} diff --git a/src/lib.rs b/src/lib.rs index bf286ab162e7..83a74612d5c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -448,6 +448,7 @@ compile_error!("`std` feature is currently required to build this crate"); pub use crate::build::{App, AppSettings, Arg, ArgGroup, ArgSettings, Propagation}; +pub use crate::derive::{Clap, FromArgMatches, IntoApp, Subcommand}; pub use crate::output::fmt::Format; pub use crate::parse::errors::{Error, ErrorKind, Result}; pub use crate::parse::{ArgMatches, OsValues, SubCommand, Values}; @@ -462,86 +463,21 @@ pub use clap_derive::{self, *}; #[cfg_attr(feature = "derive", doc(hidden))] pub use lazy_static; -use std::ffi::OsString; -use std::result::Result as StdResult; +#[doc(hidden)] +pub use mkeymap::KeyType; #[macro_use] #[allow(missing_docs)] pub mod macros; +pub mod derive; + mod build; mod mkeymap; mod output; mod parse; mod util; -#[doc(hidden)] -pub use mkeymap::KeyType; - const INTERNAL_ERROR_MSG: &str = "Fatal internal error. Please consider filing a bug \ report at https://github.com/clap-rs/clap/issues"; const INVALID_UTF8: &str = "unexpected invalid UTF-8 code point"; - -/// This trait is just a convenience on top of FromArgMatches + IntoApp -pub trait Clap: FromArgMatches + IntoApp + Sized { - /// Parse from `std::env::args()`, exit on error - fn parse() -> Self { - let matches = ::into_app().get_matches(); - ::from_arg_matches(&matches) - } - - /// Parse from `std::env::args()`, return Err on error. - fn try_parse() -> StdResult { - let matches = ::into_app().try_get_matches()?; - Ok(::from_arg_matches(&matches)) - } - - /// Parse from iterator, exit on error - fn parse_from(itr: I) -> Self - where - I: IntoIterator, - // TODO (@CreepySkeleton): discover a way to avoid cloning here - T: Into + Clone, - { - let matches = ::into_app().get_matches_from(itr); - ::from_arg_matches(&matches) - } - - /// Parse from `std::env::args()`, return Err on error. - fn try_parse_from(itr: I) -> StdResult - where - I: IntoIterator, - // TODO (@CreepySkeleton): discover a way to avoid cloning here - T: Into + Clone, - { - let matches = ::into_app().try_get_matches_from(itr)?; - Ok(::from_arg_matches(&matches)) - } -} - -/// Build an App according to the struct -/// -/// Also serves for flattening -pub trait IntoApp: Sized { - /// @TODO @release @docs - fn into_app<'b>() -> App<'b>; - /// @TODO @release @docs - fn augment_clap<'b>(app: App<'b>) -> App<'b>; -} - -/// Extract values from ArgMatches into the struct. -pub trait FromArgMatches: Sized { - /// @TODO @release @docs - fn from_arg_matches<'b>(matches: &ArgMatches) -> Self; -} - -/// @TODO @release @docs -pub trait Subcommand: Sized { - /// @TODO @release @docs - fn from_subcommand<'b>(name: &str, matches: Option<&ArgMatches>) -> Option; - /// @TODO @release @docs - fn augment_subcommands<'b>(app: App<'b>) -> App<'b>; -} - -/// @TODO @release @docs -pub trait ArgEnum {}