Skip to content

Commit

Permalink
Fix parser for #[default] attr for bool, PathBuf, and OsString
Browse files Browse the repository at this point in the history
Fixes #16
  • Loading branch information
parasyte committed Feb 12, 2024
1 parent 732d059 commit 28f67e0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
36 changes: 21 additions & 15 deletions onlyargs_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@
//! will be `-N`.
//! - If `#[long]` and `#[short]` are used together, `#[long]` takes precedence.
//! - `#[default(T)]`: Specify a default value for an argument. Where `T` is a literal value.
//! - Accepts string literals for `PathBuf`.
//! - Accepts numeric literals for numeric types.
//! - Accepts `true` and `false` idents and `"true"` and `"false"` string literals for `boolean`.
//!
//! # Supported types
//!
Expand Down Expand Up @@ -127,18 +130,16 @@ pub fn derive_parser(input: TokenStream) -> TokenStream {
};

let mut flags = vec![
ArgFlag {
name: Ident::new("help", Span::call_site()),
short: Some('h'),
doc: vec!["Show this help message.".to_string()],
output: false,
},
ArgFlag {
name: Ident::new("version", Span::call_site()),
short: Some('V'),
doc: vec!["Show the application version.".to_string()],
output: false,
},
ArgFlag::new_priv(
Ident::new("help", Span::call_site()),
Some('h'),
vec!["Show this help message.".to_string()],
),
ArgFlag::new_priv(
Ident::new("version", Span::call_site()),
Some('V'),
vec!["Show the application version.".to_string()],
),
];
flags.extend(ast.flags);

Expand Down Expand Up @@ -186,7 +187,13 @@ pub fn derive_parser(input: TokenStream) -> TokenStream {
.iter()
.filter(|&flag| flag.output)
.fold(String::new(), |mut flags, flag| {
write!(flags, "let mut {name} = false;", name = &flag.name).unwrap();
write!(
flags,
"let mut {name} = {default:?};",
name = flag.name,
default = flag.default,
)
.unwrap();
flags
});
let options_vars = ast
Expand All @@ -195,7 +202,7 @@ pub fn derive_parser(input: TokenStream) -> TokenStream {
.map(|opt| {
let name = &opt.name;
if let Some(default) = opt.default.as_ref() {
format!("let mut {name} = {default};")
format!("let mut {name} = {default}.into();")
} else {
format!("let mut {name} = None;")
}
Expand Down Expand Up @@ -367,7 +374,6 @@ pub fn derive_parser(input: TokenStream) -> TokenStream {
"\n",
);
/// The application name and version.
const VERSION: &'static str = concat!(
env!("CARGO_PKG_NAME"),
" v",
Expand Down
28 changes: 26 additions & 2 deletions onlyargs_derive/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub(crate) struct ArgFlag {
pub(crate) name: Ident,
pub(crate) short: Option<char>,
pub(crate) doc: Vec<String>,
pub(crate) default: bool,
pub(crate) output: bool,
}

Expand Down Expand Up @@ -129,7 +130,14 @@ impl Argument {
"default" => {
let mut stream = attr.tree.expect_group(Delimiter::Parenthesis)?;

default = Some(stream.try_lit()?);
default = Some(stream.try_lit().or_else(|_| {
stream
.try_ident()
.and_then(|ident| match ident.to_string().as_str() {
boolean @ ("true" | "false") => Ok(Literal::string(boolean)),
_ => Err(spanned_error("Unexpected identifier", ident.span())),
})
})?);
}
"long" => long = true,
"short" => {
Expand Down Expand Up @@ -158,7 +166,12 @@ impl Argument {
};

if path == "bool" {
args.push(Self::Flag(ArgFlag::new(name, short, doc)));
let mut flag = ArgFlag::new(name, short, doc);
match default {
Some(lit) if lit.to_string() == r#""true""# => flag.default = true,
_ => (),
}
args.push(Self::Flag(flag));
} else {
let mut opt = ArgOption::new(name, short, doc, &path).map_err(|()| {
spanned_error(
Expand Down Expand Up @@ -198,10 +211,21 @@ impl ArgFlag {
name,
short,
doc,
default: false,
output: true,
}
}

pub(crate) fn new_priv(name: Ident, short: Option<char>, doc: Vec<String>) -> Self {
ArgFlag {
name,
short,
doc,
default: false,
output: false,
}
}

pub(crate) fn as_view(&self) -> ArgView {
ArgView {
name: &self.name,
Expand Down

0 comments on commit 28f67e0

Please sign in to comment.