1use crate::{App, ArgMatches, Error};
4use std::ffi::OsString;
5
6pub trait Clap: FromArgMatches + IntoApp + Sized {
8 fn parse() -> Self {
10 let matches = <Self as IntoApp>::into_app().get_matches();
11 <Self as FromArgMatches>::from_arg_matches(&matches)
12 }
13
14 fn try_parse() -> Result<Self, Error> {
16 let matches = <Self as IntoApp>::into_app().try_get_matches()?;
17 Ok(<Self as FromArgMatches>::from_arg_matches(&matches))
18 }
19
20 fn parse_from<I, T>(itr: I) -> Self
22 where
23 I: IntoIterator<Item = T>,
24 T: Into<OsString> + Clone,
26 {
27 let matches = <Self as IntoApp>::into_app().get_matches_from(itr);
28 <Self as FromArgMatches>::from_arg_matches(&matches)
29 }
30
31 fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
33 where
34 I: IntoIterator<Item = T>,
35 T: Into<OsString> + Clone,
37 {
38 let matches = <Self as IntoApp>::into_app().try_get_matches_from(itr)?;
39 Ok(<Self as FromArgMatches>::from_arg_matches(&matches))
40 }
41}
42
43pub trait IntoApp: Sized {
47 fn into_app<'b>() -> App<'b>;
49 fn augment_clap(app: App<'_>) -> App<'_>;
51}
52
53pub trait FromArgMatches: Sized {
55 fn from_arg_matches(matches: &ArgMatches) -> Self;
57}
58
59pub trait Subcommand: Sized {
61 fn from_subcommand(name: &str, matches: Option<&ArgMatches>) -> Option<Self>;
63 fn augment_subcommands(app: App<'_>) -> App<'_>;
65}
66
67pub trait ArgEnum {}
69
70impl<T: Clap> Clap for Box<T> {
71 fn parse() -> Self {
72 Box::new(<T as Clap>::parse())
73 }
74
75 fn try_parse() -> Result<Self, Error> {
76 <T as Clap>::try_parse().map(Box::new)
77 }
78
79 fn parse_from<I, It>(itr: I) -> Self
80 where
81 I: IntoIterator<Item = It>,
82 It: Into<OsString> + Clone,
84 {
85 Box::new(<T as Clap>::parse_from(itr))
86 }
87
88 fn try_parse_from<I, It>(itr: I) -> Result<Self, Error>
89 where
90 I: IntoIterator<Item = It>,
91 It: Into<OsString> + Clone,
93 {
94 <T as Clap>::try_parse_from(itr).map(Box::new)
95 }
96}
97
98impl<T: IntoApp> IntoApp for Box<T> {
99 fn into_app<'b>() -> App<'b> {
100 <T as IntoApp>::into_app()
101 }
102 fn augment_clap(app: App<'_>) -> App<'_> {
103 <T as IntoApp>::augment_clap(app)
104 }
105}
106
107impl<T: FromArgMatches> FromArgMatches for Box<T> {
108 fn from_arg_matches(matches: &ArgMatches) -> Self {
109 Box::new(<T as FromArgMatches>::from_arg_matches(matches))
110 }
111}
112
113impl<T: Subcommand> Subcommand for Box<T> {
114 fn from_subcommand(name: &str, matches: Option<&ArgMatches>) -> Option<Self> {
115 <T as Subcommand>::from_subcommand(name, matches).map(Box::new)
116 }
117 fn augment_subcommands(app: App<'_>) -> App<'_> {
118 <T as Subcommand>::augment_subcommands(app)
119 }
120}