@@ -3,9 +3,10 @@ use std::{
33 convert:: TryInto as _,
44 env, fmt, fs,
55 path:: { Path , PathBuf } ,
6+ str:: FromStr ,
67} ;
78
8- use chrono:: { Datelike as _, TimeZone as _, Utc } ;
9+ use chrono:: { Datelike as _, Month , TimeZone as _, Utc } ;
910use glob:: glob;
1011use regex:: Regex ;
1112
@@ -38,12 +39,18 @@ impl fmt::Display for Date {
3839fn make_date_regex ( ) -> Regex {
3940 Regex :: new (
4041 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+ " ,
4754 )
4855 . unwrap ( )
4956}
@@ -52,15 +59,22 @@ fn collect_dates_from_file(date_regex: &Regex, text: &str) -> Vec<(usize, Date)>
5259 let mut line = 1 ;
5360 let mut end_of_last_cap = 0 ;
5461 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+ }
6478 } )
6579 . map ( |( byte_range, date) | {
6680 line += text[ end_of_last_cap..byte_range. end ]
@@ -182,61 +196,153 @@ mod tests {
182196
183197 #[ test]
184198 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." ) ) ;
187211 }
188212
189213 #[ 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" ) ) ;
193222 }
194223
195224 #[ test]
196225 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.
200264 " ;
201265 assert_eq ! (
202266 collect_dates_from_file( & make_date_regex( ) , text) ,
203267 vec![
204268 (
205- 2 ,
269+ 3 ,
206270 Date {
207271 year: 2021 ,
208272 month: 1 ,
209273 }
210274 ) ,
211275 (
212- 4 ,
276+ 6 ,
213277 Date {
214278 year: 2021 ,
215279 month: 2 ,
216280 }
217281 ) ,
218282 (
219- 7 ,
283+ 9 ,
220284 Date {
221285 year: 2021 ,
222286 month: 3 ,
223287 }
224288 ) ,
225289 (
226- 8 ,
290+ 11 ,
227291 Date {
228292 year: 2021 ,
229293 month: 4 ,
230294 }
231295 ) ,
232296 (
233- 14 ,
297+ 17 ,
234298 Date {
235299 year: 2021 ,
236300 month: 5 ,
237301 }
238302 ) ,
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+ ] ,
240346 ) ;
241347 }
242348}
0 commit comments