use crate::{App, ArgMatches, Error};
use std::ffi::{OsStr, OsString};
pub trait Clap: FromArgMatches + IntoApp + Sized {
fn parse() -> Self {
let matches = <Self as IntoApp>::into_app().get_matches();
<Self as FromArgMatches>::from_arg_matches(&matches)
}
fn try_parse() -> Result<Self, Error> {
let matches = <Self as IntoApp>::into_app().try_get_matches()?;
<Self as FromArgMatches>::try_from_arg_matches(&matches)
}
fn parse_from<I, T>(itr: I) -> Self
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let matches = <Self as IntoApp>::into_app().get_matches_from(itr);
<Self as FromArgMatches>::from_arg_matches(&matches)
}
fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let matches = <Self as IntoApp>::into_app().try_get_matches_from(itr)?;
<Self as FromArgMatches>::try_from_arg_matches(&matches)
}
fn update_from<I, T>(&mut self, itr: I)
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let matches = <Self as IntoApp>::into_app_for_update().get_matches_from(itr);
<Self as FromArgMatches>::update_from_arg_matches(self, &matches);
}
fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let matches = <Self as IntoApp>::into_app_for_update().try_get_matches_from(itr)?;
<Self as FromArgMatches>::update_from_arg_matches(self, &matches);
Ok(())
}
}
pub trait IntoApp: Sized {
fn into_app<'help>() -> App<'help>;
fn augment_clap(app: App<'_>) -> App<'_>;
fn into_app_for_update<'help>() -> App<'help>;
fn augment_clap_for_update(app: App<'_>) -> App<'_>;
}
pub trait FromArgMatches: Sized {
fn from_arg_matches(matches: &ArgMatches) -> Self {
Self::try_from_arg_matches(matches).unwrap_or_else(|e| e.exit())
}
fn update_from_arg_matches(&mut self, matches: &ArgMatches) {
Self::try_update_from_arg_matches(self, matches).unwrap_or_else(|e| e.exit())
}
fn try_from_arg_matches(matches: &ArgMatches) -> Result<Self, Error>;
fn try_update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error>;
}
pub trait Subcommand: Sized {
fn from_subcommand(subcommand: Option<(&str, &ArgMatches)>) -> Result<Self, Error>;
fn update_from_subcommand(
&mut self,
subcommand: Option<(&str, &ArgMatches)>,
) -> Result<(), Error>;
fn augment_subcommands(app: App<'_>) -> App<'_>;
fn augment_subcommands_for_update(app: App<'_>) -> App<'_>;
}
pub trait ArgEnum: Sized {
const VARIANTS: &'static [&'static str];
fn from_str(input: &str, case_insensitive: bool) -> Result<Self, String>;
}
pub trait TryFromOsArg: Sized {
type Error;
fn try_from_os_str_arg(os: &OsStr) -> Result<Self, Self::Error>;
#[inline]
fn try_from_os_string_arg(os: OsString) -> Result<Self, Self::Error> {
Self::try_from_os_str_arg(&os)
}
}
impl<T: Clap> Clap for Box<T> {
fn parse() -> Self {
Box::new(<T as Clap>::parse())
}
fn try_parse() -> Result<Self, Error> {
<T as Clap>::try_parse().map(Box::new)
}
fn parse_from<I, It>(itr: I) -> Self
where
I: IntoIterator<Item = It>,
It: Into<OsString> + Clone,
{
Box::new(<T as Clap>::parse_from(itr))
}
fn try_parse_from<I, It>(itr: I) -> Result<Self, Error>
where
I: IntoIterator<Item = It>,
It: Into<OsString> + Clone,
{
<T as Clap>::try_parse_from(itr).map(Box::new)
}
}
impl<T: IntoApp> IntoApp for Box<T> {
fn into_app<'help>() -> App<'help> {
<T as IntoApp>::into_app()
}
fn augment_clap(app: App<'_>) -> App<'_> {
<T as IntoApp>::augment_clap(app)
}
fn into_app_for_update<'help>() -> App<'help> {
<T as IntoApp>::into_app_for_update()
}
fn augment_clap_for_update(app: App<'_>) -> App<'_> {
<T as IntoApp>::augment_clap_for_update(app)
}
}
impl<T: FromArgMatches> FromArgMatches for Box<T> {
fn from_arg_matches(matches: &ArgMatches) -> Self {
Box::new(<T as FromArgMatches>::from_arg_matches(matches))
}
fn update_from_arg_matches(&mut self, matches: &ArgMatches) {
<T as FromArgMatches>::update_from_arg_matches(self, matches);
}
fn try_from_arg_matches(matches: &ArgMatches) -> Result<Self, Error> {
Ok(Box::new(<T as FromArgMatches>::try_from_arg_matches(
matches,
)?))
}
fn try_update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> {
<T as FromArgMatches>::try_update_from_arg_matches(self, matches)
}
}
impl<T: Subcommand> Subcommand for Box<T> {
fn from_subcommand(subcommand: Option<(&str, &ArgMatches)>) -> Result<Self, Error> {
<T as Subcommand>::from_subcommand(subcommand).map(Box::new)
}
fn update_from_subcommand(
&mut self,
subcommand: Option<(&str, &ArgMatches)>,
) -> Result<(), Error> {
<T as Subcommand>::update_from_subcommand(self, subcommand)
}
fn augment_subcommands(app: App<'_>) -> App<'_> {
<T as Subcommand>::augment_subcommands(app)
}
fn augment_subcommands_for_update(app: App<'_>) -> App<'_> {
<T as Subcommand>::augment_subcommands_for_update(app)
}
}