use crate::builder::PossibleValue;
use crate::{ArgMatches, Command, Error};
use std::ffi::OsString;
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```")]
pub trait Parser: FromArgMatches + CommandFactory + Sized {
fn parse() -> Self {
let mut matches = <Self as CommandFactory>::command().get_matches();
let res = <Self as FromArgMatches>::from_arg_matches_mut(&mut matches)
.map_err(format_error::<Self>);
match res {
Ok(s) => s,
Err(e) => {
e.exit()
}
}
}
fn try_parse() -> Result<Self, Error> {
let mut matches = ok!(<Self as CommandFactory>::command().try_get_matches());
<Self as FromArgMatches>::from_arg_matches_mut(&mut matches).map_err(format_error::<Self>)
}
fn parse_from<I, T>(itr: I) -> Self
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut matches = <Self as CommandFactory>::command().get_matches_from(itr);
let res = <Self as FromArgMatches>::from_arg_matches_mut(&mut matches)
.map_err(format_error::<Self>);
match res {
Ok(s) => s,
Err(e) => {
e.exit()
}
}
}
fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut matches = ok!(<Self as CommandFactory>::command().try_get_matches_from(itr));
<Self as FromArgMatches>::from_arg_matches_mut(&mut matches).map_err(format_error::<Self>)
}
fn update_from<I, T>(&mut self, itr: I)
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut matches = <Self as CommandFactory>::command_for_update().get_matches_from(itr);
let res = <Self as FromArgMatches>::update_from_arg_matches_mut(self, &mut matches)
.map_err(format_error::<Self>);
if let Err(e) = res {
e.exit()
}
}
fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
let mut matches =
ok!(<Self as CommandFactory>::command_for_update().try_get_matches_from(itr));
<Self as FromArgMatches>::update_from_arg_matches_mut(self, &mut matches)
.map_err(format_error::<Self>)
}
}
pub trait CommandFactory: Sized {
fn command() -> Command;
fn command_for_update() -> Command;
}
pub trait FromArgMatches: Sized {
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```no_run")]
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```no_run")]
fn from_arg_matches(matches: &ArgMatches) -> Result<Self, Error>;
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```no_run")]
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```no_run")]
fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result<Self, Error> {
Self::from_arg_matches(matches)
}
fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error>;
fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> {
self.update_from_arg_matches(matches)
}
}
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```")]
pub trait Args: FromArgMatches + Sized {
fn group_id() -> Option<crate::Id> {
None
}
fn augment_args(cmd: Command) -> Command;
fn augment_args_for_update(cmd: Command) -> Command;
}
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```")]
pub trait Subcommand: FromArgMatches + Sized {
fn augment_subcommands(cmd: Command) -> Command;
fn augment_subcommands_for_update(cmd: Command) -> Command;
fn has_subcommand(name: &str) -> bool;
}
#[cfg_attr(not(feature = "derive"), doc = " ```ignore")]
#[cfg_attr(feature = "derive", doc = " ```")]
pub trait ValueEnum: Sized + Clone {
fn value_variants<'a>() -> &'a [Self];
fn from_str(input: &str, ignore_case: bool) -> Result<Self, String> {
Self::value_variants()
.iter()
.find(|v| {
v.to_possible_value()
.expect("ValueEnum::value_variants contains only values with a corresponding ValueEnum::to_possible_value")
.matches(input, ignore_case)
})
.cloned()
.ok_or_else(|| format!("invalid variant: {}", input))
}
fn to_possible_value(&self) -> Option<PossibleValue>;
}
impl<T: Parser> Parser for Box<T> {
fn parse() -> Self {
Box::new(<T as Parser>::parse())
}
fn try_parse() -> Result<Self, Error> {
<T as Parser>::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 Parser>::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 Parser>::try_parse_from(itr).map(Box::new)
}
}
impl<T: CommandFactory> CommandFactory for Box<T> {
fn command<'help>() -> Command {
<T as CommandFactory>::command()
}
fn command_for_update<'help>() -> Command {
<T as CommandFactory>::command_for_update()
}
}
impl<T: FromArgMatches> FromArgMatches for Box<T> {
fn from_arg_matches(matches: &ArgMatches) -> Result<Self, Error> {
<T as FromArgMatches>::from_arg_matches(matches).map(Box::new)
}
fn from_arg_matches_mut(matches: &mut ArgMatches) -> Result<Self, Error> {
<T as FromArgMatches>::from_arg_matches_mut(matches).map(Box::new)
}
fn update_from_arg_matches(&mut self, matches: &ArgMatches) -> Result<(), Error> {
<T as FromArgMatches>::update_from_arg_matches(self, matches)
}
fn update_from_arg_matches_mut(&mut self, matches: &mut ArgMatches) -> Result<(), Error> {
<T as FromArgMatches>::update_from_arg_matches_mut(self, matches)
}
}
impl<T: Args> Args for Box<T> {
fn augment_args(cmd: Command) -> Command {
<T as Args>::augment_args(cmd)
}
fn augment_args_for_update(cmd: Command) -> Command {
<T as Args>::augment_args_for_update(cmd)
}
}
impl<T: Subcommand> Subcommand for Box<T> {
fn augment_subcommands(cmd: Command) -> Command {
<T as Subcommand>::augment_subcommands(cmd)
}
fn augment_subcommands_for_update(cmd: Command) -> Command {
<T as Subcommand>::augment_subcommands_for_update(cmd)
}
fn has_subcommand(name: &str) -> bool {
<T as Subcommand>::has_subcommand(name)
}
}
fn format_error<I: CommandFactory>(err: crate::Error) -> crate::Error {
let mut cmd = I::command();
err.format(&mut cmd)
}