@@ -6,13 +6,15 @@ use crate::rtw_config::RTWConfig;
66use crate :: rtw_core:: activity:: { Activity , OngoingActivity } ;
77use crate :: rtw_core:: clock:: Clock ;
88use crate :: rtw_core:: datetimew:: DateTimeW ;
9+ use crate :: rtw_core:: durationw:: DurationW ;
910use crate :: rtw_core:: service:: ActivityService ;
1011use crate :: rtw_core:: storage:: Storage ;
1112use crate :: rtw_core:: ActivityId ;
1213use crate :: rtw_core:: { Description , Tags } ;
1314use crate :: service:: Service ;
1415use crate :: timeline:: render_days;
1516use clap:: ArgMatches ;
17+ use itertools:: Itertools ;
1618
1719type ActivityWithId = ( ActivityId , Activity ) ;
1820
@@ -24,7 +26,7 @@ pub enum RTWAction {
2426 Start ( DateTimeW , Tags , Option < Description > ) ,
2527 Track ( ( DateTimeW , DateTimeW ) , Tags , Option < Description > ) ,
2628 Stop ( DateTimeW , Option < ActivityId > ) ,
27- Summary ( ( DateTimeW , DateTimeW ) , bool , bool ) ,
29+ Summary ( ( DateTimeW , DateTimeW ) , bool , bool , bool ) ,
2830 DumpICal ( ( DateTimeW , DateTimeW ) ) ,
2931 Continue ,
3032 Delete ( ActivityId ) ,
@@ -48,6 +50,27 @@ enum OptionalOrAmbiguousOrNotFound {
4850 NotFound ( ActivityId ) ,
4951}
5052
53+ fn merge_same_tags ( activities : & [ ActivityWithId ] ) -> Vec < ( ActivityId , Activity , DurationW , usize ) > {
54+ let uniques: Vec < ActivityWithId > = activities
55+ . iter ( )
56+ . cloned ( )
57+ . unique_by ( |( _i, activity) | activity. get_title ( ) )
58+ . collect ( ) ;
59+ uniques
60+ . iter ( )
61+ . cloned ( )
62+ . map ( |( i, activity) | {
63+ let same_tag = activities
64+ . iter ( )
65+ . filter ( |( _i, other) | activity. get_title ( ) == other. get_title ( ) ) ;
66+ let durations: Vec < DurationW > = same_tag. map ( |( _i, a) | a. get_duration ( ) ) . collect ( ) ;
67+ let segments = durations. len ( ) ;
68+ let duration = durations. into_iter ( ) . sum ( ) ;
69+ ( i, activity, duration, segments)
70+ } )
71+ . collect ( )
72+ }
73+
5174fn get_ongoing_activity < S : Storage > (
5275 id_maybe : Option < ActivityId > ,
5376 service : & Service < S > ,
@@ -90,12 +113,13 @@ where
90113 Ok ( RTWAction :: Stop ( abs_stop_time, stopped_id_maybe) )
91114 }
92115 ( "summary" , Some ( sub_m) ) => {
93- let ( ( range_start, range_end) , display_id, display_description) =
116+ let ( ( range_start, range_end) , display_id, display_description, report ) =
94117 cli_helper:: parse_summary_args ( sub_m, clock) ?;
95118 Ok ( RTWAction :: Summary (
96119 ( range_start, range_end) ,
97120 display_id,
98121 display_description,
122+ report,
99123 ) )
100124 }
101125 ( "timeline" , Some ( sub_m) ) => {
@@ -128,7 +152,7 @@ where
128152 Ok ( RTWAction :: Cancel ( cancelled_id_maybe) )
129153 }
130154 ( "dump" , Some ( sub_m) ) => {
131- let ( ( range_start, range_end) , _display_id, _description) =
155+ let ( ( range_start, range_end) , _display_id, _description, _report ) =
132156 cli_helper:: parse_summary_args ( sub_m, clock) ?;
133157 Ok ( RTWAction :: DumpICal ( ( range_start, range_end) ) )
134158 }
@@ -191,7 +215,7 @@ where
191215 }
192216 }
193217 }
194- RTWAction :: Summary ( ( range_start, range_end) , display_id, display_description) => {
218+ RTWAction :: Summary ( ( range_start, range_end) , display_id, display_description, report ) => {
195219 let activities = service. get_finished_activities ( ) ?;
196220 let activities: Vec < ( ActivityId , Activity ) > = activities
197221 . iter ( )
@@ -207,6 +231,25 @@ where
207231 . unwrap_or_default ( ) ;
208232 if activities. is_empty ( ) {
209233 println ! ( "No filtered data found." ) ;
234+ } else if report {
235+ let activities_report = merge_same_tags ( activities. as_slice ( ) ) ;
236+ for ( _id, finished, duration, segments) in activities_report {
237+ let singular_or_plural = if segments <= 1 {
238+ String :: from ( "segment" )
239+ } else {
240+ // segments > 1
241+ String :: from ( "segments" )
242+ } ;
243+ let output = format ! (
244+ "{:width$} {} ({} {})" ,
245+ finished. get_title( ) ,
246+ duration,
247+ segments,
248+ singular_or_plural,
249+ width = longest_title
250+ ) ;
251+ println ! ( "{}" , output)
252+ }
210253 } else {
211254 for ( id, finished) in activities {
212255 let output = format ! (
0 commit comments