Skip to content

Commit

Permalink
Merge pull request #301 from pacak/simplify-parse-any
Browse files Browse the repository at this point in the history
Convert checker function inside ParseAny into a trait object
  • Loading branch information
pacak authored Sep 24, 2023
2 parents a5b2501 + c76ed23 commit 748138f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 24 deletions.
18 changes: 12 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1480,16 +1480,22 @@ where
/// # See also
/// [`literal`] - a specialized version of `any` that tries to parse a fixed literal
#[must_use]
pub fn any<I, T, F>(metavar: &str, check: F) -> ParseAny<T, I, F>
pub fn any<I, T, F>(metavar: &str, check: F) -> ParseAny<T>
where
I: FromStr + 'static,
F: Fn(I) -> Option<T>,
F: Fn(I) -> Option<T> + 'static,
<I as std::str::FromStr>::Err: std::fmt::Display,
{
ParseAny {
metavar: [(metavar, Style::Metavar)][..].into(),
help: None,
check,
ctx: PhantomData,
check: Box::new(move |os: std::ffi::OsString| {
match crate::from_os_str::parse_os_str::<I>(os) {
Ok(v) => check(v),
Err(_) => None,
}
}),

anywhere: false,
}
}
Expand All @@ -1507,8 +1513,8 @@ where
/// [`any`] - a generic version of `literal` that uses function to decide if value is to be parsed
/// or not.
#[must_use]
pub fn literal(val: &'static str) -> ParseAny<(), String, impl Fn(String) -> Option<()>> {
any("", move |s| if s == val { Some(()) } else { None })
pub fn literal(val: &'static str) -> ParseAny<()> {
any("", move |s: String| if s == val { Some(()) } else { None })
.metavar(&[(val, crate::buffer::Style::Literal)][..])
}

Expand Down
28 changes: 10 additions & 18 deletions src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -847,15 +847,14 @@ where

/// Consume an arbitrary value that satisfies a condition, created with [`any`], implements
/// [`anywhere`](ParseAny::anywhere).
pub struct ParseAny<T, I, F> {
pub struct ParseAny<T> {
pub(crate) metavar: Doc,
pub(crate) help: Option<Doc>,
pub(crate) ctx: PhantomData<(I, T)>,
pub(crate) check: F,
pub(crate) check: Box<dyn Fn(OsString) -> Option<T>>,
pub(crate) anywhere: bool,
}

impl<T, I, F> ParseAny<T, I, F> {
impl<T> ParseAny<T> {
pub(crate) fn item(&self) -> Item {
Item::Any {
metavar: self.metavar.clone(),
Expand Down Expand Up @@ -894,27 +893,20 @@ impl<T, I, F> ParseAny<T, I, F> {
}
}

impl<F, I, T> Parser<T> for ParseAny<T, I, F>
where
I: FromStr + 'static,
F: Fn(I) -> Option<T>,
<I as std::str::FromStr>::Err: std::fmt::Display,
{
impl<T> Parser<T> for ParseAny<T> {
fn eval(&self, args: &mut State) -> Result<T, Error> {
for (ix, x) in args.items_iter() {
let (os, next) = match x {
Arg::Short(_, next, os) | Arg::Long(_, next, os) => (os, *next),
Arg::ArgWord(os) | Arg::Word(os) | Arg::PosWord(os) => (os, false),
};
if let Ok(i) = parse_os_str::<I>(os.clone()) {
if let Some(t) = (self.check)(i) {
args.remove(ix);
if next {
args.remove(ix + 1);
}

return Ok(t);
if let Some(i) = (self.check)(os.clone()) {
args.remove(ix);
if next {
args.remove(ix + 1);
}

return Ok(i);
}
if !self.anywhere {
break;
Expand Down

0 comments on commit 748138f

Please sign in to comment.