2 combinator
::{alt, eof, preceded, rest, terminated}
,
5 stream
::{Offset, Stream}
,
9 use crate::bstr
::{BStr, ByteSlice}
;
11 pub(crate) fn newline
<'a
, E
: ParserError
<&'a
[u8]>>(i
: &mut &'a
[u8]) -> PResult
<&'a
[u8], E
> {
12 alt((b
"\n", b
"\r\n")).parse_next(i
)
15 fn subject_and_body
<'a
, E
: ParserError
<&'a
[u8]>>(i
: &mut &'a
[u8]) -> PResult
<(&'a BStr
, Option
<&'a BStr
>), E
> {
17 let start
= i
.checkpoint();
19 match take_till1
::<_
, _
, E
>(|c
| c
== b'
\n'
|| c
== b'
\r'
).parse_next(i
) {
21 let consumed_bytes
= i
.offset_from(&start
);
22 match preceded((newline
::<E
>, newline
::<E
>), rest
).parse_next(i
) {
24 let body
= (!body
.is_empty()).then(|| body
.as_bstr());
25 return Ok((start_i
[0usize
..consumed_bytes
].as_bstr(), body
));
27 Err(_
) => match i
.next_token() {
33 Err(_
) => match i
.next_token() {
41 rest
.map(|r
: &[u8]| (r
.as_bstr(), None
)).parse_next(i
)
44 /// Returns title and body, without separator
45 pub fn message(mut input
: &[u8]) -> (&BStr
, Option
<&BStr
>) {
46 terminated(subject_and_body
::<()>, eof
)
47 .parse_next(&mut input
)
48 .expect("cannot fail")