@@ -2,21 +2,36 @@ use super::{
2
2
util:: { parse_timezone_offset, split2_at_space} ,
3
3
Error ,
4
4
} ;
5
- use crate :: { parsed:: Signature , Time } ;
5
+ use crate :: { parsed:: Signature , Sign , Time } ;
6
6
use bstr:: { BStr , ByteSlice } ;
7
7
use btoi:: btoi;
8
8
use hex:: FromHex ;
9
9
use nom:: {
10
- bytes:: complete:: tag,
11
- bytes:: complete:: { take_while1, take_while_m_n} ,
12
- character:: is_alphabetic,
13
- sequence:: { preceded, terminated} ,
14
- IResult ,
10
+ bytes:: {
11
+ complete:: {
12
+ take_till,
13
+ take_until,
14
+ take_while,
15
+ tag,
16
+ take_while1,
17
+ take_while_m_n
18
+ }
19
+ } ,
20
+ branch:: alt,
21
+ character:: {
22
+ is_digit,
23
+ is_alphabetic
24
+ } ,
25
+ sequence:: {
26
+ delimited,
27
+ pair,
28
+ tuple,
29
+ preceded,
30
+ terminated
31
+ } ,
32
+ IResult
15
33
} ;
16
- use nom:: sequence:: { delimited, pair, tuple} ;
17
- use nom:: bytes:: complete:: { take_until, take_till, take_while} ;
18
- use nom:: character:: is_digit;
19
- use nom:: branch:: alt;
34
+ use nom:: bytes:: complete:: take;
20
35
21
36
#[ derive( PartialEq , Eq , Debug , Hash ) ]
22
37
pub struct Tag < ' data > {
@@ -93,11 +108,40 @@ fn is_hex_digit_lc(b: u8) -> bool {
93
108
const NL : & [ u8 ] = b"\n " ;
94
109
const SPACE : & [ u8 ] = b" " ;
95
110
pub ( crate ) fn parse_signature_nom ( i : & [ u8 ] ) -> IResult < & [ u8 ] , Signature , Error > {
96
- let ( i, ( name, email, time_in_seconds, tzofs) ) = tuple ( ( terminated ( take_till ( |b| b == b'<' ) , tag ( b"<" ) ) ,
97
- terminated ( take_till ( |b| b == b'>' ) , tag ( b"> " ) ) ,
98
- terminated ( take_till ( |b| b == SPACE [ 0 ] ) , tag ( SPACE ) ) ,
99
- pair ( alt ( ( tag ( b"-" ) , tag ( b"+" ) ) ) , take_while_m_n ( 4usize , 4 , |b| is_digit ( b) ) ) ) ) ( i) ?;
100
- unimplemented ! ( "parse signature" )
111
+ let ( i, ( name, email, time_in_seconds, tzsign, tzhour, tzminute) ) = tuple ( (
112
+ terminated ( take_until ( & b" <" [ ..] ) , take ( 2usize ) ) ,
113
+ terminated ( take_until ( & b"> " [ ..] ) , take ( 2usize ) ) ,
114
+ terminated ( take_until ( SPACE ) , take ( 1usize ) ) ,
115
+ alt ( ( tag ( b"-" ) , tag ( b"+" ) ) ) ,
116
+ take_while_m_n ( 2usize , 2 , |b| is_digit ( b) ) ,
117
+ take_while_m_n ( 2usize , 2 , |b| is_digit ( b) ) ,
118
+ ) ) ( i)
119
+ . map_err ( Error :: context (
120
+ "tagger <name> <<email>> <time seconds since epoch> <+|-><HHMM>" ,
121
+ ) ) ?;
122
+
123
+ let sign = if tzsign[ 0 ] == b'-' {
124
+ Sign :: Minus
125
+ } else {
126
+ Sign :: Plus
127
+ } ;
128
+ let hours = btoi :: < i32 > ( & tzhour)
129
+ . map_err ( |e| nom:: Err :: Error ( Error :: ParseIntegerError ( "invalid 'hours' string" , tzhour. to_owned ( ) , e) ) ) ?;
130
+ let minutes = btoi :: < i32 > ( & tzminute)
131
+ . map_err ( |e| nom:: Err :: Error ( Error :: ParseIntegerError ( "invalid 'minutes' string" , tzminute. to_owned ( ) , e) ) ) ?;
132
+ let offset = ( hours * 3600 + minutes * 60 ) ;
133
+
134
+ Ok ( ( i, Signature {
135
+ name : name. as_bstr ( ) ,
136
+ email : email. as_bstr ( ) ,
137
+ time : Time {
138
+ time : btoi :: < u32 > ( time_in_seconds) . map_err ( |e| {
139
+ nom:: Err :: Error ( Error :: ParseIntegerError ( "Could parse to seconds" , time_in_seconds. to_owned ( ) , e) )
140
+ } ) ?,
141
+ offset,
142
+ sign
143
+ }
144
+ } ) )
101
145
}
102
146
103
147
pub ( crate ) fn parse_tag_nom ( i : & [ u8 ] ) -> IResult < & [ u8 ] , Tag , Error > {
@@ -114,11 +158,15 @@ pub(crate) fn parse_tag_nom(i: &[u8]) -> IResult<&[u8], Tag, Error> {
114
158
. map_err ( Error :: context ( "type <object kind>" ) ) ?;
115
159
let kind = crate :: Kind :: from_bytes ( kind) ?;
116
160
117
- let ( i, tag_version) = terminated ( preceded ( tag ( b"tag " ) , take_while1 ( |b| b != NL [ 0 ] ) ) , tag ( NL ) ) ( i)
118
- . map_err ( Error :: context ( "tag <version>" ) ) ?;
161
+ let ( i, tag_version) =
162
+ terminated ( preceded ( tag ( b"tag " ) , take_while1 ( |b| b != NL [ 0 ] ) ) , tag ( NL ) ) ( i)
163
+ . map_err ( Error :: context ( "tag <version>" ) ) ?;
119
164
120
- let ( i, tagger) = terminated ( preceded ( tag ( b"tagger " ) , take_while1 ( |b| b != NL [ 0 ] ) ) , tag ( NL ) ) ( i)
121
- . map_err ( Error :: context ( "tagger <signature>" ) ) ?;
165
+ let ( i, tagger) = terminated (
166
+ preceded ( tag ( b"tagger " ) , take_while1 ( |b| b != NL [ 0 ] ) ) ,
167
+ tag ( NL ) ,
168
+ ) ( i)
169
+ . map_err ( Error :: context ( "tagger <signature>" ) ) ?;
122
170
unimplemented ! ( "parse message nom" )
123
171
}
124
172
0 commit comments