nom_both/lib.rs
1//! `nom-both` is an extension of [nom](https://docs.rs/nom) to provide special `both_` parser.
2//!
3//! ## Examples
4//!
5//! The following example show a quick example.
6//!
7//! ```
8//! use nom::branch::*;
9//! use nom::bytes::complete::*;
10//! use nom::IResult;
11//! use nom_both::both_parser;
12//!
13//! #[both_parser]
14//! pub fn both_opt_parser(s: &str) -> IResult<&str, Option<&str>> {
15//! let (s, _) = tag("1")(s)?;
16//! let (s, x) = both_opt(tag("2"))(s)?;
17//! let (s, _) = tag("2")(s)?;
18//! let (s, _) = tag("3")(s)?;
19//! Ok((s, x))
20//! }
21//!
22//! #[both_parser]
23//! pub fn both_alt_parser(s: &str) -> IResult<&str, &str> {
24//! let (s, _) = tag("1")(s)?;
25//! let (s, x) = both_alt(tag("22"), tag("2"))(s)?;
26//! let (s, _) = tag("2")(s)?;
27//! let (s, _) = tag("3")(s)?;
28//! Ok((s, x))
29//! }
30//!
31//! fn main() {
32//! let ret = both_opt_parser("123");
33//! assert_eq!("None", format!("{:?}", ret.unwrap().1));
34//!
35//! let ret = both_alt_parser("1223");
36//! assert_eq!("\"2\"", format!("{:?}", ret.unwrap().1));
37//! }
38//! ```
39
40use nom::IResult;
41pub use nom_both_macros::both_parser;
42
43pub fn some<'a, I, O, F>(f: F) -> impl Fn(I) -> IResult<I, Option<O>>
44where
45 F: Fn(I) -> IResult<I, O>,
46{
47 move |i: I| {
48 let (i, x) = f(i)?;
49 Ok((i, Some(x)))
50 }
51}
52
53pub fn none<'a, I, O, F>(_f: F) -> impl Fn(I) -> IResult<I, Option<O>>
54where
55 F: Fn(I) -> IResult<I, O>,
56{
57 move |i: I| Ok((i, None))
58}
59
60pub fn alt_left<'a, I, O, F, G>(f: F, _g: G) -> impl Fn(I) -> IResult<I, O>
61where
62 F: Fn(I) -> IResult<I, O>,
63 G: Fn(I) -> IResult<I, O>,
64{
65 move |i: I| {
66 let (i, x) = f(i)?;
67 Ok((i, x))
68 }
69}
70
71pub fn alt_right<'a, I, O, F, G>(_f: F, g: G) -> impl Fn(I) -> IResult<I, O>
72where
73 F: Fn(I) -> IResult<I, O>,
74 G: Fn(I) -> IResult<I, O>,
75{
76 move |i: I| {
77 let (i, x) = g(i)?;
78 Ok((i, x))
79 }
80}