@@ -8,72 +8,51 @@ use crate::{
8
8
mod decode {
9
9
use crate :: bstr:: { BStr , ByteSlice } ;
10
10
use nom:: branch:: alt;
11
- use nom:: bytes:: complete:: { tag, take_till1, take_until1 } ;
12
- use nom:: combinator:: { all_consuming, map , opt , peek , recognize } ;
11
+ use nom:: bytes:: complete:: { tag, take_till1} ;
12
+ use nom:: combinator:: all_consuming;
13
13
use nom:: error:: ParseError ;
14
- use nom:: multi:: { fold_many1, length_data} ;
15
- use nom:: sequence:: { pair, terminated} ;
14
+ use nom:: sequence:: pair;
16
15
use nom:: IResult ;
16
+ use std:: convert:: TryInto ;
17
17
18
18
fn newline < ' a , E : ParseError < & ' a [ u8 ] > > ( i : & ' a [ u8 ] ) -> IResult < & ' a [ u8 ] , & ' a [ u8 ] , E > {
19
19
alt ( ( tag ( b"\r \n " ) , tag ( b"\n " ) ) ) ( i)
20
20
}
21
21
22
- fn subject < ' a , E : ParseError < & ' a [ u8 ] > > ( i : & ' a [ u8 ] ) -> IResult < & ' a [ u8 ] , & ' a BStr , E > {
23
- map (
24
- length_data ( peek ( fold_many1 (
25
- recognize ( terminated ( take_till1 ( |c| c == b'\n' ) , tag ( b"\n " ) ) ) ,
26
- || 0 ,
27
- |acc : usize , item : & ' a [ u8 ] | acc + item. len ( ) ,
28
- ) ) ) ,
29
- |s| s. as_bstr ( ) ,
30
- ) ( i)
31
- }
32
-
33
- #[ cfg( test) ]
34
- mod tests {
35
- use super :: * ;
36
-
37
- #[ test]
38
- fn subject_ending_in_newline_with_newline ( ) {
39
- assert_eq ! ( subject:: <( ) >( b"a\n b\n " ) . unwrap( ) , ( b"" . as_ref( ) , b"a\n b\n c" . as_bstr( ) ) ) ;
40
- }
41
-
42
- #[ test]
43
- fn subject_with_single_newline ( ) {
44
- assert_eq ! ( subject:: <( ) >( b"a\n " ) . unwrap( ) , ( b"" . as_ref( ) , b"a\n " . as_bstr( ) ) ) ;
45
- }
46
- }
47
-
48
- /// Parse a signature from the bytes input `i` using `nom`.
49
22
pub fn nomfoo < ' a , E : ParseError < & ' a [ u8 ] > > ( i : & ' a [ u8 ] ) -> IResult < & ' a [ u8 ] , ( & ' a BStr , Option < & ' a BStr > ) , E > {
50
- let ( rest, subject) = opt ( terminated ( subject, pair ( newline, newline) ) ) ( i) ?;
51
- Ok ( (
52
- & [ ] ,
53
- match subject {
54
- Some ( subject) => ( subject. as_bstr ( ) , ( !rest. is_empty ( ) ) . then ( || rest. as_bstr ( ) ) ) ,
55
- None => ( i. as_bstr ( ) , None ) ,
56
- } ,
57
- ) )
23
+ let mut c = i;
24
+ while !c. is_empty ( ) {
25
+ c = match take_till1 :: < _ , _ , E > ( |c| c == b'\n' || c == b'\r' ) ( c) {
26
+ Ok ( ( i1, segment) ) => match pair :: < _ , _ , _ , E , _ , _ > ( newline, newline) ( i1) {
27
+ Ok ( ( body, _) ) => {
28
+ // SAFETY: the pointers are pointing to the same slice.
29
+ #[ allow( unsafe_code) ]
30
+ let consumed_bytes = unsafe { segment. as_ptr_range ( ) . end . offset_from ( i. as_ptr ( ) ) } ;
31
+ return Ok ( (
32
+ & [ ] ,
33
+ (
34
+ & i[ 0usize ..consumed_bytes. try_into ( ) . expect ( "positive offset" ) ] . as_bstr ( ) ,
35
+ ( !body. is_empty ( ) ) . then ( || body. as_bstr ( ) ) ,
36
+ ) ,
37
+ ) ) ;
38
+ }
39
+ Err ( _) => match i1. get ( 1 ..) {
40
+ Some ( next) => next,
41
+ None => break ,
42
+ } ,
43
+ } ,
44
+ Err ( _) => match c. get ( 1 ..) {
45
+ Some ( next) => next,
46
+ None => break ,
47
+ } ,
48
+ } ;
49
+ }
50
+ Ok ( ( & [ ] , ( i. as_bstr ( ) , None ) ) )
58
51
}
59
52
60
53
/// Returns title and body, without separator
61
54
pub fn bytes ( message : & [ u8 ] ) -> ( & BStr , Option < & BStr > ) {
62
55
all_consuming ( nomfoo :: < ( ) > ) ( message) . expect ( "cannot fail" ) . 1
63
- // match message
64
- // .find(b"\n\n")
65
- // .map(|pos| (2, pos))
66
- // .or_else(|| message.find(b"\r\n\r\n").map(|pos| (4, pos)))
67
- // {
68
- // Some((sep_len, end_of_title)) => {
69
- // let body = &message[end_of_title + sep_len..];
70
- // (
71
- // message[..end_of_title].as_bstr(),
72
- // if body.is_empty() { None } else { Some(body.as_bstr()) },
73
- // )
74
- // }
75
- // None => (message.as_bstr(), None),
76
- // }
77
56
}
78
57
}
79
58
0 commit comments