#![doc(hidden)]
pub mod const_exprs;
#[macro_export]
#[doc(hidden)]
macro_rules! __parse_arg {
( err => $args:expr, $name:ident, $typ:ty, ) => {
let $name = $name.get_raw(&$args);
};
( ok => $args:expr, $name:ident, $typ:ty, ) => {
let $name = $name.get_raw(&$args).map(|a| a.ok()).flatten();
};
( => $args:expr, $name:ident, $typ:ty, ) => {
let $name = $name
.get(&$args)
.expect("Tried to unwrap argument that wasn't passed")
.expect("Tried to unwrap argument that failed to parse");
};
( err => $args:expr, $name:ident, $typ:ty, $default:literal ) => {
let $name = $name.get_raw(&$args).unwrap_or_else(|| {
::std::result::Result::Ok($crate::__sarge_default::<$typ, _>($default))
});
};
( err => $args:expr, $name:ident, $typ:ty, $default:expr ) => {
let $name = $name.get_raw(&$args).unwrap_or_else(|| {
::std::result::Result::Ok($crate::__sarge_default_expr::<$typ>($default))
});
};
( ok => $args:expr, $name:ident, $typ:ty, $default:literal ) => {
let $name = match $name.get_raw(&$args) {
None => Some($crate::__sarge_default::<$typ, _>($default)),
Some(Ok(v)) => Some(v),
Some(Err(_)) => None,
};
};
( ok => $args:expr, $name:ident, $typ:ty, $default:expr ) => {
let $name = match $name.get_raw(&$args) {
None => Some($crate::__sarge_default_expr::<$typ>($default)),
Some(Ok(v)) => Some(v),
Some(Err(_)) => None,
};
};
( => $args:expr, $name:ident, $typ:ty, $default:literal ) => {
let $name = match $name.get_raw(&$args) {
None => $crate::__sarge_default::<$typ, _>($default),
Some(Ok(v)) => v,
Some(Err(_)) => panic!("Tried to unwrap argument that failed to parse"),
};
};
( => $args:expr, $name:ident, $typ:ty, $default:expr ) => {
let $name = match $name.get_raw(&$args) {
None => $crate::__sarge_default_expr::<$typ>($default),
Some(Ok(v)) => v,
Some(Err(_)) => panic!("Tried to unwrap argument that failed to parse"),
};
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __arg_typ {
( $name:ident, err, $typ:ty, ) => {
$crate::ArgResult<$typ>
};
( $name:ident, err, $typ:ty, $default:expr ) => {
$crate::DefaultedArgResult<$typ>
};
( $name:ident, ok, $typ:ty, ) => {
::std::option::Option<$typ>
};
( $name:ident, ok, $typ:ty, $default:expr ) => {
::std::option::Option<$typ>
};
( $name:ident, $typ:ty, $( $default:expr )? ) => {
$typ
};
}
#[macro_export]
#[doc(hidden)]
macro_rules! __var_tag {
( $long:ident $( $doc:literal )* ) => {{
let tag = $crate::tag::long($crate::__replace!(::std::stringify!($long), '_', '-'));
#[cfg(feature = "help")]
let tag = {
let mut s = ::std::string::String::new();
$(
s.push_str($doc);
s.push('\n');
)*
s.pop();
tag.doc(s)
};
tag
}};
( $short:literal $long:ident $( $doc:literal )* ) => {{
let tag = $crate::tag::both($short, $crate::__replace!(::std::stringify!($long), '_', '-'));
#[cfg(feature = "help")]
let tag = {
let mut s = ::std::string::String::new();
$(
s.push_str($doc);
s.push('\n');
)*
s.pop();
tag.doc(s)
};
tag
}};
( $long:ident $env:ident $( $doc:literal )* ) => {{
let tag = $crate::tag::long($crate::__replace!(::std::stringify!($long), '_', '-'))
.env(::std::stringify!($env));
#[cfg(feature = "help")]
let tag = {
let mut s = ::std::string::String::new();
$(
s.push_str($doc);
s.push('\n');
)*
s.pop();
tag.doc(s)
};
tag
}};
( $short:literal $long:ident $env:ident $( $doc:literal )* ) => {{
let tag = $crate::tag::both($short, $crate::__replace!(::std::stringify!($long), '_', '-'))
.env(::std::stringify!($env));
#[cfg(feature = "help")]
let tag = {
let mut s = ::std::string::String::new();
$(
s.push_str($doc);
s.push('\n');
)*
s.pop();
tag.doc(s)
};
tag
}};
}
#[macro_export]
macro_rules! sarge {
(
@__struct
[ $( $doc:literal )* ]
[ $( $struct_meta:meta )* ]
$v:vis $name:ident, $(
$( #[doc = $field_doc:literal] )*
$( # $spec:ident )?
$( $short:literal )?
$( @ $env:ident )?
$av:vis
$long:ident : $typ:ty
$( = $default:expr )?
),* $(,)?
) => {
$(#[$struct_meta])*
$v struct $name {
$(
$(#[doc = $field_doc])*
$av $long: $crate::__arg_typ!($long, $( $spec, )? $typ, $( $default )?),
)*
}
impl $name {
#[cfg(feature = "help")]
#[allow(unused)]
pub fn help() -> ::std::string::String {
let mut parser = $crate::ArgumentReader::new();
let mut doc = ::std::string::String::new();
$(
doc.push_str($doc);
doc.push('\n');
)*
doc.pop();
if !doc.is_empty() {
parser.doc = Some(doc);
}
$(
parser.add::<$typ>(
$crate::__var_tag!($( $short )? $long $( $env )? $( $field_doc )*)
);
)*
parser.help()
}
#[cfg(feature = "help")]
#[allow(unused)]
pub fn print_help() {
print!("{}", Self::help());
}
#[allow(unused)]
pub fn parse() -> std::result::Result<(Self, std::vec::Vec<std::string::String>), $crate::ArgParseError> {
Self::parse_provided(
std::env::args(),
std::env::vars(),
)
}
#[allow(unused)]
pub fn parse_env<
K: std::convert::AsRef<str>,
V: std::convert::AsRef<str>,
I: std::iter::IntoIterator<Item = (K, V)>,
>(env: I) -> std::result::Result<Self, $crate::ArgParseError> {
::std::result::Result::Ok(Self::parse_provided(
std::option::Option::<&'static str>::None,
env,
)?.0)
}
#[allow(clippy::missing_panics_doc)]
#[allow(unused)]
pub fn parse_cli<
A: std::convert::AsRef<str>,
I: std::iter::IntoIterator<Item = A>,
>(args: I) -> std::result::Result<(Self, std::vec::Vec<std::string::String>), $crate::ArgParseError> {
Self::parse_provided(
args,
std::option::Option::<(&'static str, &'static str)>::None,
)
}
#[allow(unused)]
pub fn parse_provided<
A: std::convert::AsRef<str>,
IA: std::iter::IntoIterator<Item = A>,
K: std::convert::AsRef<str>,
V: std::convert::AsRef<str>,
IE: std::iter::IntoIterator<Item = (K, V)>,
>(
cli: IA,
env: IE,
) -> std::result::Result<
(Self, std::vec::Vec<std::string::String>), $crate::ArgParseError
>
{
let mut parser = $crate::ArgumentReader::new();
$(
let $long = parser.add::<$typ>(
$crate::__var_tag!($( $short )? $long $( $env )? )
);
)*
let args = parser.parse_provided(cli, env)?;
$(
$crate::__parse_arg!($( $spec )? => args, $long, $typ, $( $default )?);
)*
let me = Self {$(
$long,
)*};
::std::result::Result::Ok((me, args.into()))
}
}
};
(
@__collect
[ $( $doc:literal )* ]
[ $( $struct_meta:meta )* ]
#[doc = $next_doc:literal]
$($rest:tt)*
) => {
$crate::sarge! {
@__collect
[ $( $doc )* $next_doc ]
[ $( $struct_meta )* doc = $next_doc ]
$($rest)*
}
};
(
@__collect
[ $( $doc:literal )* ]
[ $( $struct_meta:meta )* ]
#[$next_meta:meta]
$($rest:tt)*
) => {
$crate::sarge! {
@__collect
[ $( $doc )* ]
[ $( $struct_meta )* $next_meta ]
$($rest)*
}
};
(
@__collect
[ $( $doc:literal )* ]
[ $( $struct_meta:meta )* ]
$v:vis $name:ident, $($rest:tt)*
) => {
$crate::sarge! {
@__struct
[ $( $doc )* ]
[ $( $struct_meta )* ]
$v $name, $($rest)*
}
};
(
$( $tt:tt )*
) => {
$crate::sarge! {
@__collect
[]
[]
$( $tt )*
}
};
}