Skip to content

Commit 5534e57

Browse files
committed
Expose the Either parser
This will make it easier to build Parser implementations without having to implement the trait manually
1 parent a44b52e commit 5534e57

File tree

2 files changed

+21
-67
lines changed

2 files changed

+21
-67
lines changed

benchmarks/benches/json.rs

+18-66
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ use codspeed_criterion_compat::*;
55
use nom::{
66
branch::alt,
77
bytes::{tag, take},
8-
character::{anychar, char, multispace0, none_of},
9-
combinator::{map, map_opt, map_res, value, verify},
8+
character::{char, multispace0, none_of},
9+
combinator::{map, map_opt, map_res, success, value, verify},
1010
error::{Error, ErrorKind, FromExternalError, ParseError},
1111
multi::{fold, separated_list0},
12-
number::double,
13-
number::recognize_float,
12+
number::{double, recognize_float},
1413
sequence::{delimited, preceded, separated_pair},
15-
Check, Complete, Emit, IResult, Mode, OutputM, Parser,
14+
Check, Complete, Either, Emit, IResult, OutputM, Parser,
1615
};
1716
use nom_language::error::VerboseError;
1817

@@ -68,69 +67,22 @@ fn character<
6867
'a,
6968
E: ParseError<&'a str> + FromExternalError<&'a str, ParseIntError> + FromExternalError<&'a str, ()>,
7069
>() -> impl Parser<&'a str, Output = char, Error = E> {
71-
Character { e: PhantomData }
72-
/*let (input, c) = none_of("\"")(input)?;
73-
if c == '\\' {
74-
alt((
75-
map_res(anychar, |c| {
76-
Ok(match c {
77-
'"' | '\\' | '/' => c,
78-
'b' => '\x08',
79-
'f' => '\x0C',
80-
'n' => '\n',
81-
'r' => '\r',
82-
't' => '\t',
83-
_ => return Err(()),
84-
})
85-
}),
86-
preceded(char('u'), unicode_escape()),
87-
))
88-
.parse(input)
89-
} else {
90-
Ok((input, c))
91-
}*/
92-
}
93-
94-
struct Character<E> {
95-
e: PhantomData<E>,
96-
}
97-
98-
impl<'a, E> Parser<&'a str> for Character<E>
99-
where
100-
E: ParseError<&'a str>
101-
+ FromExternalError<&'a str, ParseIntError>
102-
+ FromExternalError<&'a str, ()>,
103-
{
104-
type Output = char;
105-
106-
type Error = E;
107-
108-
fn process<OM: nom::OutputMode>(
109-
&mut self,
110-
input: &'a str,
111-
) -> nom::PResult<OM, &'a str, Self::Output, Self::Error> {
112-
let (input, c): (&str, char) =
113-
none_of("\"").process::<OutputM<Emit, OM::Error, OM::Incomplete>>(input)?;
114-
if c == '\\' {
115-
alt((
116-
map_res(anychar, |c| {
117-
Ok(match c {
118-
'"' | '\\' | '/' => c,
119-
'b' => '\x08',
120-
'f' => '\x0C',
121-
'n' => '\n',
122-
'r' => '\r',
123-
't' => '\t',
124-
_ => return Err(()),
125-
})
126-
}),
127-
preceded(char('u'), unicode_escape()),
128-
))
129-
.process::<OM>(input)
70+
none_of("\"").flat_map(|c| {
71+
if c != '\\' {
72+
Either::Left(success(c))
13073
} else {
131-
Ok((input, OM::Output::bind(|| c)))
74+
Either::Right(alt((
75+
value('\\', tag("\\")),
76+
value('\"', tag("\"")),
77+
value('\n', tag("n")),
78+
value('\r', tag("r")),
79+
value('\t', tag("t")),
80+
value('\x08', tag("b")),
81+
value('\x0C', tag("f")),
82+
preceded(char('u'), unicode_escape()),
83+
)))
13284
}
133-
}
85+
})
13486
}
13587

13688
fn string<

src/internal.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -781,8 +781,10 @@ impl<
781781
}
782782

783783
/// Alternate between two Parser implementations with the same result type.
784-
pub(crate) enum Either<F, G> {
784+
pub enum Either<F, G> {
785+
/// Left parser alternative
785786
Left(F),
787+
/// Right parser alternative
786788
Right(G),
787789
}
788790

0 commit comments

Comments
 (0)