mirror of
https://gitee.com/openharmony/third_party_rust_nom
synced 2024-11-23 15:40:19 +00:00
add the satisfy combinator, that checks a predicate on the next char
This commit is contained in:
parent
b2ed755e27
commit
5108ed18d5
@ -37,6 +37,39 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Recognizes one character and checks that it satisfies a predicate
|
||||
///
|
||||
/// *Complete version*: Will return an error if there's not enough input data.
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
|
||||
/// # use nom::character::complete::satisfy;
|
||||
/// # fn main() {
|
||||
/// fn parser(i: &str) -> IResult<&str, char> {
|
||||
/// satisfy(|c| c == 'a' || c == 'b')(i)
|
||||
/// }
|
||||
/// assert_eq!(parser("abc"), Ok(("bc", 'a')));
|
||||
/// assert_eq!(parser("cd"), Err(Err::Error(Error::new("cd", ErrorKind::Satisfy))));
|
||||
/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Satisfy))));
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error>
|
||||
where
|
||||
I: Slice<RangeFrom<usize>> + InputIter,
|
||||
<I as InputIter>::Item: AsChar,
|
||||
F: Fn(char) -> bool,
|
||||
{
|
||||
move |i: I| match (i).iter_elements().next().map(|t| {
|
||||
let c = t.as_char();
|
||||
let b = cond(c);
|
||||
(c, b)
|
||||
}) {
|
||||
Some((c, true)) => Ok((i.slice(c.len()..), c)),
|
||||
_ => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Satisfy))),
|
||||
}
|
||||
}
|
||||
|
||||
/// Recognizes one of the provided characters.
|
||||
///
|
||||
/// *Complete version*: Will return an error if there's not enough input data.
|
||||
|
@ -39,6 +39,40 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Recognizes one character and checks that it satisfies a predicate
|
||||
///
|
||||
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # use nom::{Err, error::{ErrorKind, Error}, Needed, IResult};
|
||||
/// # use nom::character::streaming::satisfy;
|
||||
/// # fn main() {
|
||||
/// fn parser(i: &str) -> IResult<&str, char> {
|
||||
/// satisfy(|c| c == 'a' || c == 'b')(i)
|
||||
/// }
|
||||
/// assert_eq!(parser("abc"), Ok(("bc", 'a')));
|
||||
/// assert_eq!(parser("cd"), Err(Err::Error(Error::new("cd", ErrorKind::Satisfy))));
|
||||
/// assert_eq!(parser(""), Err(Err::Incomplete(Needed::Unknown)));
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn satisfy<F, I, Error: ParseError<I>>(cond: F) -> impl Fn(I) -> IResult<I, char, Error>
|
||||
where
|
||||
I: Slice<RangeFrom<usize>> + InputIter,
|
||||
<I as InputIter>::Item: AsChar,
|
||||
F: Fn(char) -> bool,
|
||||
{
|
||||
move |i: I| match (i).iter_elements().next().map(|t| {
|
||||
let c = t.as_char();
|
||||
let b = cond(c);
|
||||
(c, b)
|
||||
}) {
|
||||
None => Err(Err::Incomplete(Needed::Unknown)),
|
||||
Some((_, false)) => Err(Err::Error(Error::from_error_kind(i, ErrorKind::Satisfy))),
|
||||
Some((c, true)) => Ok((i.slice(c.len()..), c)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Recognizes one of the provided characters.
|
||||
///
|
||||
/// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there's not enough input data.
|
||||
|
@ -400,6 +400,7 @@ pub enum ErrorKind {
|
||||
Many0Count,
|
||||
Many1Count,
|
||||
Float,
|
||||
Satisfy,
|
||||
}
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
@ -459,6 +460,7 @@ pub fn error_to_u32(e: &ErrorKind) -> u32 {
|
||||
ErrorKind::Many0Count => 72,
|
||||
ErrorKind::Many1Count => 73,
|
||||
ErrorKind::Float => 74,
|
||||
ErrorKind::Satisfy => 75,
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,6 +522,7 @@ impl ErrorKind {
|
||||
ErrorKind::Many0Count => "Count occurrence of >=0 patterns",
|
||||
ErrorKind::Many1Count => "Count occurrence of >=1 patterns",
|
||||
ErrorKind::Float => "Float",
|
||||
ErrorKind::Satisfy => "Satisfy",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user