Skip to content

Commit

Permalink
feat: Add Parser::default_value
Browse files Browse the repository at this point in the history
  • Loading branch information
epage committed Dec 18, 2023
1 parent 07b8a99 commit 5f5f27c
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/combinator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
//! - [`cond`]: Conditional combinator. Wraps another parser and calls it if the condition is met
//! - [`Parser::flat_map`]: method to map a new parser from the output of the first parser, then apply that parser over the rest of the input
//! - [`Parser::value`]: method to replace the result of a parser
//! - [`Parser::default_value`]: method to replace the result of a parser
//! - [`Parser::void`]: method to discard the result of a parser
//! - [`Parser::map`]: method to map a function on the result of a parser
//! - [`Parser::and_then`]: Applies a second parser over the output of the first one
Expand Down
42 changes: 42 additions & 0 deletions src/combinator/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,48 @@ where
}
}

/// Implementation of [`Parser::default_value`]
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct DefaultValue<F, I, O, O2, E>
where
F: Parser<I, O, E>,
O2: core::default::Default,
{
parser: F,
o2: core::marker::PhantomData<O2>,
i: core::marker::PhantomData<I>,
o: core::marker::PhantomData<O>,
e: core::marker::PhantomData<E>,
}

impl<F, I, O, O2, E> DefaultValue<F, I, O, O2, E>
where
F: Parser<I, O, E>,
O2: core::default::Default,
{
#[inline(always)]
pub(crate) fn new(parser: F) -> Self {
Self {
parser,
o2: Default::default(),
i: Default::default(),
o: Default::default(),
e: Default::default(),
}
}
}

impl<F, I, O, O2, E> Parser<I, O2, E> for DefaultValue<F, I, O, O2, E>
where
F: Parser<I, O, E>,
O2: core::default::Default,
{
#[inline]
fn parse_next(&mut self, input: &mut I) -> PResult<O2, E> {
(self.parser).parse_next(input).map(|_| O2::default())
}
}

/// Implementation of [`Parser::void`]
#[cfg_attr(nightly, warn(rustdoc::missing_doc_code_examples))]
pub struct Void<F, I, O, E>
Expand Down
24 changes: 24 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,30 @@ pub trait Parser<I, O, E> {
Value::new(self, val)
}

/// Produce a type's default value
///
/// # Example
///
/// ```rust
/// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
/// use winnow::ascii::alpha1;
/// # fn main() {
///
/// let mut parser = alpha1.default_value::<u32>();
///
/// assert_eq!(parser.parse_peek("abcd"), Ok(("", 0)));
/// assert_eq!(parser.parse_peek("123abcd;"), Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice))));
/// # }
/// ```
#[inline(always)]
fn default_value<O2>(self) -> DefaultValue<Self, I, O, O2, E>
where
Self: core::marker::Sized,
O2: core::default::Default,
{
DefaultValue::new(self)
}

/// Discards the output of the `Parser`
///
/// # Example
Expand Down

0 comments on commit 5f5f27c

Please sign in to comment.