1- use crate :: quartiles:: quartiles;
21use crate :: types:: { Contribution , Contributions , Range , Timeline , Year } ;
3- use anyhow:: { Context , Result } ;
2+ use crate :: { git, quartiles:: quartiles} ;
3+ use anyhow:: Result ;
44use chrono:: prelude:: * ;
5- use std:: { collections:: HashMap , convert:: TryFrom } ;
5+ use std:: { cmp :: { max , min } , collections:: HashMap , convert:: TryFrom } ;
66
77/// The internal state of the parser
88#[ derive( Debug , Default ) ]
99pub struct ParseState {
1010 years_map : HashMap < i32 , Year > ,
1111 days : HashMap < NaiveDate , usize > ,
12+ before : Option < NaiveDate > ,
13+ after : Option < NaiveDate > ,
1214}
1315
1416impl ParseState {
1517 /// Add a single day to the map of years
1618 pub fn update_years ( & mut self , date : NaiveDate ) {
1719 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+ } ;
1828 let mut year = self . years_map . entry ( y) . or_insert ( Year {
1929 year : y. to_string ( ) ,
2030 total : 0 ,
2131 // range: Range::default,
2232 // Always show full year
2333 range : Range {
24- start : format ! ( "{}-01-01" , y ) ,
25- end : format ! ( "{}-12-31" , y ) ,
34+ start : start . format ( "%y-%m-%d" ) . to_string ( ) ,
35+ end : end . format ( "%y-%m-%d" ) . to_string ( ) ,
2636 } ,
2737 } ) ;
2838 year. total += 1 ;
@@ -40,15 +50,6 @@ impl ParseState {
4050 pub fn update_days ( & mut self , date : NaiveDate ) {
4151 * self . days . entry ( date) . or_insert ( 0 ) += 1 ;
4252 }
43-
44- pub fn parse_date ( & self , line : & str ) -> Result < Option < NaiveDate > > {
45- if line. trim ( ) . is_empty ( ) {
46- // Empty lines are allowed, but skipped
47- return Ok ( None ) ;
48- }
49- let date: NaiveDate = line. parse ( ) . context ( format ! ( "Invalid date {}" , line) ) ?;
50- Ok ( Some ( date) )
51- }
5253}
5354
5455/// Backfill missing days with zero commits
@@ -155,12 +156,49 @@ impl Parser {
155156 }
156157 }
157158
159+ /// Set the minimum date of the timeline. Commits older than the given date
160+ /// will not be counted and won't be in the final output
161+ pub fn set_before ( & mut self , before : String ) -> Result < & mut Self > {
162+ let before = git:: parse_date ( & before) ?;
163+ if let Some ( before) = before {
164+ self . state . before = Some ( before) ;
165+ }
166+ Ok ( self )
167+ }
168+
169+ /// Set the maximum date of the timeline. Commits newer than the given date
170+ /// will not be counted and won't be in the final output
171+ pub fn set_after ( & mut self , after : String ) -> Result < & mut Self > {
172+ let after = git:: parse_date ( & after) ?;
173+ if let Some ( after) = after {
174+ self . state . after = Some ( after) ;
175+ }
176+ Ok ( self )
177+ }
178+
179+ fn outside_date_range ( & self , day : NaiveDate ) -> bool {
180+ if let Some ( before) = self . state . before {
181+ if day < before {
182+ return true ;
183+ }
184+ }
185+ if let Some ( after) = self . state . after {
186+ if day > after {
187+ return true ;
188+ }
189+ }
190+ false
191+ }
192+
158193 /// Execute the parsing step
159194 pub fn parse ( & mut self ) -> Result < Timeline > {
160195 let input = self . input . clone ( ) ;
161196 for line in input. lines ( ) {
162- let day = self . state . parse_date ( & line) ?;
197+ let day = git :: parse_date ( & line) ?;
163198 if let Some ( d) = day {
199+ if self . outside_date_range ( d) {
200+ continue ;
201+ }
164202 self . state . update_days ( d) ;
165203 self . state . update_years ( d) ;
166204 }
0 commit comments