@@ -3,9 +3,10 @@ use std::{
3
3
convert:: TryInto as _,
4
4
env, fmt, fs,
5
5
path:: { Path , PathBuf } ,
6
+ str:: FromStr ,
6
7
} ;
7
8
8
- use chrono:: { Datelike as _, TimeZone as _, Utc } ;
9
+ use chrono:: { Datelike as _, Month , TimeZone as _, Utc } ;
9
10
use glob:: glob;
10
11
use regex:: Regex ;
11
12
@@ -38,12 +39,18 @@ impl fmt::Display for Date {
38
39
fn make_date_regex ( ) -> Regex {
39
40
Regex :: new (
40
41
r"(?x) # insignificant whitespace mode
41
- <!--\s*
42
- [dD]ate:\s*
43
- (?P<y>\d{4}) # year
44
- -
45
- (?P<m>\d{2}) # month
46
- \s*-->" ,
42
+ (<!--\s*
43
+ date-check:\s*
44
+ (?P<m1>\D+)\s+
45
+ (?P<y1>\d{4})\s*-->
46
+ )
47
+ |
48
+ (<!--\s*
49
+ date-check\s*-->\s+
50
+ (?P<m2>\D+)\s+
51
+ (?P<y2>\d{4})\b
52
+ )
53
+ " ,
47
54
)
48
55
. unwrap ( )
49
56
}
@@ -52,15 +59,22 @@ fn collect_dates_from_file(date_regex: &Regex, text: &str) -> Vec<(usize, Date)>
52
59
let mut line = 1 ;
53
60
let mut end_of_last_cap = 0 ;
54
61
date_regex
55
- . captures_iter ( & text)
56
- . map ( |cap| {
57
- (
58
- cap. get ( 0 ) . unwrap ( ) . range ( ) ,
59
- Date {
60
- year : cap[ "y" ] . parse ( ) . unwrap ( ) ,
61
- month : cap[ "m" ] . parse ( ) . unwrap ( ) ,
62
- } ,
63
- )
62
+ . captures_iter ( text)
63
+ . filter_map ( |cap| {
64
+ if let ( Some ( month) , Some ( year) , None , None ) | ( None , None , Some ( month) , Some ( year) ) = (
65
+ cap. name ( "m1" ) ,
66
+ cap. name ( "y1" ) ,
67
+ cap. name ( "m2" ) ,
68
+ cap. name ( "y2" ) ,
69
+ ) {
70
+ let year = year. as_str ( ) . parse ( ) . expect ( "year" ) ;
71
+ let month = Month :: from_str ( month. as_str ( ) )
72
+ . expect ( "month" )
73
+ . number_from_month ( ) ;
74
+ Some ( ( cap. get ( 0 ) . expect ( "all" ) . range ( ) , Date { year, month } ) )
75
+ } else {
76
+ None
77
+ }
64
78
} )
65
79
. map ( |( byte_range, date) | {
66
80
line += text[ end_of_last_cap..byte_range. end ]
@@ -182,61 +196,153 @@ mod tests {
182
196
183
197
#[ test]
184
198
fn test_date_regex ( ) {
185
- let regex = make_date_regex ( ) ;
186
- assert ! ( regex. is_match( "foo <!-- date: 2021-01 --> bar" ) ) ;
199
+ let regex = & make_date_regex ( ) ;
200
+ assert ! ( regex. is_match( "<!-- date-check: jan 2021 -->" ) ) ;
201
+ assert ! ( regex. is_match( "<!-- date-check: january 2021 -->" ) ) ;
202
+ assert ! ( regex. is_match( "<!-- date-check: Jan 2021 -->" ) ) ;
203
+ assert ! ( regex. is_match( "<!-- date-check: January 2021 -->" ) ) ;
204
+ assert ! ( regex. is_match( "<!-- date-check --> jan 2021" ) ) ;
205
+ assert ! ( regex. is_match( "<!-- date-check --> january 2021" ) ) ;
206
+ assert ! ( regex. is_match( "<!-- date-check --> Jan 2021" ) ) ;
207
+ assert ! ( regex. is_match( "<!-- date-check --> January 2021" ) ) ;
208
+
209
+ assert ! ( regex. is_match( "<!-- date-check --> jan 2021 " ) ) ;
210
+ assert ! ( regex. is_match( "<!-- date-check --> jan 2021." ) ) ;
187
211
}
188
212
189
213
#[ test]
190
- fn test_date_regex_capitalized ( ) {
191
- let regex = make_date_regex ( ) ;
192
- assert ! ( regex. is_match( "foo <!-- Date: 2021-08 --> bar" ) ) ;
214
+ fn test_date_regex_fail ( ) {
215
+ let regexes = & make_date_regex ( ) ;
216
+ assert ! ( !regexes. is_match( "<!-- date-check: jan 221 -->" ) ) ;
217
+ assert ! ( !regexes. is_match( "<!-- date-check: jan 20221 -->" ) ) ;
218
+ assert ! ( !regexes. is_match( "<!-- date-check: 01 2021 -->" ) ) ;
219
+ assert ! ( !regexes. is_match( "<!-- date-check --> jan 221" ) ) ;
220
+ assert ! ( !regexes. is_match( "<!-- date-check --> jan 20222" ) ) ;
221
+ assert ! ( !regexes. is_match( "<!-- date-check --> 01 2021" ) ) ;
193
222
}
194
223
195
224
#[ test]
196
225
fn test_collect_dates_from_file ( ) {
197
- let text = "Test1\n <!-- date: 2021-01 -->\n Test2\n Foo<!-- date: 2021-02 \
198
- -->\n Test3\n Test4\n Foo<!-- date: 2021-03 -->Bar\n <!-- date: 2021-04 \
199
- -->\n Test5\n Test6\n Test7\n <!-- date: \n \n 2021-05 -->\n Test8
226
+ let text = r"
227
+ Test1
228
+ <!-- date-check: jan 2021 -->
229
+ Test2
230
+ Foo<!-- date-check: february 2021
231
+ -->
232
+ Test3
233
+ Test4
234
+ Foo<!-- date-check: Mar 2021 -->Bar
235
+ <!-- date-check:April 2021
236
+ -->
237
+ Test5
238
+ Test6
239
+ Test7
240
+ <!-- date-check:
241
+
242
+ may 2021 -->
243
+ Test8
244
+ Test1
245
+ <!-- date-check --> jan 2021
246
+ Test2
247
+ Foo<!-- date-check
248
+ --> february 2021
249
+ Test3
250
+ Test4
251
+ Foo<!-- date-check --> mar 2021 Bar
252
+ <!-- date-check
253
+ --> apr 2021
254
+ Test5
255
+ Test6
256
+ Test7
257
+ <!-- date-check
258
+
259
+ --> may 2021
260
+ Test8
261
+ <!--
262
+ date-check
263
+ --> june 2021.
200
264
" ;
201
265
assert_eq ! (
202
266
collect_dates_from_file( & make_date_regex( ) , text) ,
203
267
vec![
204
268
(
205
- 2 ,
269
+ 3 ,
206
270
Date {
207
271
year: 2021 ,
208
272
month: 1 ,
209
273
}
210
274
) ,
211
275
(
212
- 4 ,
276
+ 6 ,
213
277
Date {
214
278
year: 2021 ,
215
279
month: 2 ,
216
280
}
217
281
) ,
218
282
(
219
- 7 ,
283
+ 9 ,
220
284
Date {
221
285
year: 2021 ,
222
286
month: 3 ,
223
287
}
224
288
) ,
225
289
(
226
- 8 ,
290
+ 11 ,
227
291
Date {
228
292
year: 2021 ,
229
293
month: 4 ,
230
294
}
231
295
) ,
232
296
(
233
- 14 ,
297
+ 17 ,
234
298
Date {
235
299
year: 2021 ,
236
300
month: 5 ,
237
301
}
238
302
) ,
239
- ]
303
+ (
304
+ 20 ,
305
+ Date {
306
+ year: 2021 ,
307
+ month: 1 ,
308
+ }
309
+ ) ,
310
+ (
311
+ 23 ,
312
+ Date {
313
+ year: 2021 ,
314
+ month: 2 ,
315
+ }
316
+ ) ,
317
+ (
318
+ 26 ,
319
+ Date {
320
+ year: 2021 ,
321
+ month: 3 ,
322
+ }
323
+ ) ,
324
+ (
325
+ 28 ,
326
+ Date {
327
+ year: 2021 ,
328
+ month: 4 ,
329
+ }
330
+ ) ,
331
+ (
332
+ 34 ,
333
+ Date {
334
+ year: 2021 ,
335
+ month: 5 ,
336
+ }
337
+ ) ,
338
+ (
339
+ 38 ,
340
+ Date {
341
+ year: 2021 ,
342
+ month: 6 ,
343
+ }
344
+ ) ,
345
+ ] ,
240
346
) ;
241
347
}
242
348
}
0 commit comments