Skip to content

Instantly share code, notes, and snippets.

@CreepySkeleton
Created February 3, 2020 09:25
Show Gist options
  • Save CreepySkeleton/3518a3d104c3e1c451be40e6a8b0032b to your computer and use it in GitHub Desktop.
Save CreepySkeleton/3518a3d104c3e1c451be40e6a8b0032b to your computer and use it in GitHub Desktop.
"Multiple traits" approach for clap_derive
/// This trait is just a convenience on top of FromArgMatches + IntoApp
///
/// All the methods are provided.
trait Clap: FromArgMatches + IntoApp + Sized {
/// Parse from `std::env::args()`, exit on error
fn parse() -> Self {
let matches = <Self as IntoApp>::into_app().get_matches();
<Self as FromArgMatches>::from_argmatches(matches)
}
/// Parse from `std::env::args()`, return Err on error.
fn try_parse() -> Result<Self, ClapErr> {
let matches = <Self as IntoApp>::into_app().try_get_matches()?;
Ok(<Self as FromArgMatches>::from_argmatches(matches))
}
/// Parse from iterator, exit on error
pub fn parse_from<I, T>(itr: I) -> #name
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone
{
let matches = <Self as IntoApp>::into_app().get_matches_from(itr);
<Self as FromArgMatches>::from_argmatches(matches)
}
/// Parse from `std::env::args()`, return Err on error.
fn try_parse_from(itr: I) -> Result<Self, ClapErr>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone
{
let matches = <Self as IntoApp>::into_app().try_get_matches_from(itr)?;
Ok(<Self as FromArgMatches>::from_argmatches(matches))
}
}
/// Build an App according to the struct
///
/// Also serves fro flatening
trait IntoApp: Sized {
fn into_app<'b>() -> clap::App<'b>;
fn augment_clap<'b>(app: clap::App<'b>) -> App<'b>;
}
/// Extract values from ArgMatches into the struct.
trait FromArgMatches: Sized {
fn from_argmatches<'b>(app: clap::App<'b>) -> Self;
}
trait Subcommand {
fn from_subcommand<'b>(name: &str, matches: ArgMatches) -> Option<Self>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment