11use crate :: types:: { Contribution , Contributions , Range , Timeline , Year } ;
22use crate :: { git, quartiles:: quartiles} ;
3- use anyhow:: Result ;
3+ use anyhow:: { Context , Result } ;
44use chrono:: prelude:: * ;
5- use std:: { cmp:: { max, min} , collections:: HashMap , convert:: TryFrom } ;
5+ use std:: {
6+ cmp:: { max, min} ,
7+ collections:: HashMap ,
8+ convert:: TryFrom ,
9+ } ;
610
711/// The internal state of the parser
812#[ derive( Debug , Default ) ]
@@ -17,33 +21,23 @@ impl ParseState {
1721 /// Add a single day to the map of years
1822 pub fn update_years ( & mut self , date : NaiveDate ) {
1923 let y = date. year ( ) ;
20- let start = match self . before {
21- Some ( before) => max ( before, date) ,
22- None => date,
23- } ;
24- let end = match self . after {
25- Some ( after) => min ( after, date) ,
26- None => date,
27- } ;
24+ let date_str = date. format ( "%Y-%m-%d" ) . to_string ( ) ;
25+
2826 let mut year = self . years_map . entry ( y) . or_insert ( Year {
2927 year : y. to_string ( ) ,
3028 total : 0 ,
3129 // range: Range::default,
3230 // Always show full year
3331 range : Range {
34- start : start . format ( "%y-%m-%d" ) . to_string ( ) ,
35- end : end . format ( "%y-%m-%d" ) . to_string ( ) ,
32+ start : date_str . clone ( ) ,
33+ end : date_str . clone ( ) ,
3634 } ,
3735 } ) ;
38- year. total += 1 ;
3936
40- // let date = date.format("%Y-%m-%d").to_string();
41- // if year.range.start.is_empty() || date < year.range.start {
42- // year.range.start = date.clone();
43- // }
44- // if year.range.end.is_empty() || date > year.range.end {
45- // year.range.end = date
46- // }
37+ year. range . start = min ( year. range . start . clone ( ) , date_str. clone ( ) ) ;
38+ year. range . end = max ( year. range . end . clone ( ) , date_str) ;
39+
40+ year. total += 1 ;
4741 }
4842
4943 /// Add a single day to the map of days
@@ -53,13 +47,19 @@ impl ParseState {
5347}
5448
5549/// Backfill missing days with zero commits
56- fn backfill ( year : i32 , days : & mut HashMap < NaiveDate , usize > ) {
50+ fn backfill ( year : i32 , days : & mut HashMap < NaiveDate , usize > ) -> Result < ( ) > {
51+ let last_day = days
52+ . keys ( )
53+ . max_by_key ( |key| * key)
54+ . cloned ( )
55+ . context ( "cannot get last day for backfilling" ) ?;
5756 for d in NaiveDate :: from_ymd ( year, 1 , 1 ) . iter_days ( ) {
58- if d. year ( ) != year {
57+ if d > last_day {
5958 break ;
6059 }
6160 days. entry ( d) . or_insert ( 0 ) ;
6261 }
62+ Ok ( ( ) )
6363}
6464
6565// Each cell in the timeline is shaded with one of 5 possible colors. These
@@ -122,7 +122,7 @@ impl TryFrom<&ParseState> for Timeline {
122122 . into_iter ( )
123123 . filter ( |( date, _commits) | date. year ( ) . to_string ( ) == year. year )
124124 . collect ( ) ;
125- backfill ( year. year . parse :: < i32 > ( ) ?, & mut year_contribs) ;
125+ backfill ( year. year . parse :: < i32 > ( ) ?, & mut year_contribs) ? ;
126126 let commits: Vec < usize > = year_contribs. values ( ) . cloned ( ) . collect ( ) ;
127127 let quartiles = quartiles ( & commits) ?;
128128
@@ -176,14 +176,14 @@ impl Parser {
176176 Ok ( self )
177177 }
178178
179- fn outside_date_range ( & self , day : NaiveDate ) -> bool {
179+ fn out_of_range ( & self , day : NaiveDate ) -> bool {
180180 if let Some ( before) = self . state . before {
181- if day < before {
181+ if day >= before {
182182 return true ;
183183 }
184184 }
185185 if let Some ( after) = self . state . after {
186- if day > after {
186+ if day <= after {
187187 return true ;
188188 }
189189 }
@@ -196,7 +196,7 @@ impl Parser {
196196 for line in input. lines ( ) {
197197 let day = git:: parse_date ( & line) ?;
198198 if let Some ( d) = day {
199- if self . outside_date_range ( d) {
199+ if self . out_of_range ( d) {
200200 continue ;
201201 }
202202 self . state . update_days ( d) ;
@@ -238,6 +238,34 @@ mod test {
238238 assert_eq ! ( parser. parse( ) . unwrap( ) . years, expected) ;
239239 }
240240
241+ #[ test]
242+ fn test_parse_years_range ( ) {
243+ let input = r###"
244+ 2020-04-15
245+ 2020-04-15
246+ 2020-04-16
247+ 2020-04-17
248+ 2020-04-17
249+ 2020-04-17
250+ 2020-04-17
251+ 2020-04-18
252+ "### ;
253+
254+ let range = Range {
255+ start : "2020-04-16" . to_string ( ) ,
256+ end : "2020-04-17" . to_string ( ) ,
257+ } ;
258+ let expected = vec ! [ Year {
259+ year: "2020" . to_string( ) ,
260+ total: 5 ,
261+ range: range,
262+ } ] ;
263+ let mut parser = Parser :: new ( input. to_string ( ) ) ;
264+ parser. set_before ( "2020-04-18" . into ( ) ) . unwrap ( ) ;
265+ parser. set_after ( "2020-04-15" . into ( ) ) . unwrap ( ) ;
266+ assert_eq ! ( parser. parse( ) . unwrap( ) . years, expected) ;
267+ }
268+
241269 #[ test]
242270 fn test_intensities ( ) {
243271 let quartiles = [ 0 , 1 , 11 , 22 , 32 ] ;
0 commit comments