@@ -8,9 +8,10 @@ use serde_json::error::Category;
88include ! ( concat!( env!( "OUT_DIR" ) , "/objdiff.report.rs" ) ) ;
99include ! ( concat!( env!( "OUT_DIR" ) , "/objdiff.report.serde.rs" ) ) ;
1010
11- pub const REPORT_VERSION : u32 = 1 ;
11+ pub const REPORT_VERSION : u32 = 2 ;
1212
1313impl Report {
14+ /// Attempts to parse the report as binary protobuf or JSON.
1415 pub fn parse ( data : & [ u8 ] ) -> Result < Self > {
1516 if data. is_empty ( ) {
1617 bail ! ( std:: io:: Error :: from( std:: io:: ErrorKind :: UnexpectedEof ) ) ;
@@ -25,6 +26,7 @@ impl Report {
2526 Ok ( report)
2627 }
2728
29+ /// Attempts to parse the report as JSON, migrating from the legacy report format if necessary.
2830 fn from_json ( bytes : & [ u8 ] ) -> Result < Self , serde_json:: Error > {
2931 match serde_json:: from_slice :: < Self > ( bytes) {
3032 Ok ( report) => Ok ( report) ,
@@ -43,16 +45,23 @@ impl Report {
4345 }
4446 }
4547
48+ /// Migrates the report to the latest version.
49+ /// Fails if the report version is newer than supported.
4650 pub fn migrate ( & mut self ) -> Result < ( ) > {
4751 if self . version == 0 {
4852 self . migrate_v0 ( ) ?;
4953 }
54+ if self . version == 1 {
55+ self . migrate_v1 ( ) ?;
56+ }
5057 if self . version != REPORT_VERSION {
5158 bail ! ( "Unsupported report version: {}" , self . version) ;
5259 }
5360 Ok ( ( ) )
5461 }
5562
63+ /// Adds `complete_code`, `complete_data`, `complete_code_percent`, and `complete_data_percent`
64+ /// to measures, and sets `progress_categories` in unit metadata.
5665 fn migrate_v0 ( & mut self ) -> Result < ( ) > {
5766 let Some ( measures) = & mut self . measures else {
5867 bail ! ( "Missing measures in report" ) ;
@@ -61,15 +70,16 @@ impl Report {
6170 let Some ( unit_measures) = & mut unit. measures else {
6271 bail ! ( "Missing measures in report unit" ) ;
6372 } ;
64- let Some ( metadata) = & mut unit. metadata else {
65- bail ! ( "Missing metadata in report unit" ) ;
73+ let mut complete = false ;
74+ if let Some ( metadata) = & mut unit. metadata {
75+ if metadata. module_name . is_some ( ) || metadata. module_id . is_some ( ) {
76+ metadata. progress_categories = vec ! [ "modules" . to_string( ) ] ;
77+ } else {
78+ metadata. progress_categories = vec ! [ "dol" . to_string( ) ] ;
79+ }
80+ complete = metadata. complete . unwrap_or ( false ) ;
6681 } ;
67- if metadata. module_name . is_some ( ) || metadata. module_id . is_some ( ) {
68- metadata. progress_categories = vec ! [ "modules" . to_string( ) ] ;
69- } else {
70- metadata. progress_categories = vec ! [ "dol" . to_string( ) ] ;
71- }
72- if metadata. complete . unwrap_or ( false ) {
82+ if complete {
7383 unit_measures. complete_code = unit_measures. total_code ;
7484 unit_measures. complete_data = unit_measures. total_data ;
7585 unit_measures. complete_code_percent = 100.0 ;
@@ -84,10 +94,42 @@ impl Report {
8494 measures. complete_data += unit_measures. complete_data ;
8595 }
8696 measures. calc_matched_percent ( ) ;
97+ self . calculate_progress_categories ( ) ;
8798 self . version = 1 ;
8899 Ok ( ( ) )
89100 }
90101
102+ /// Adds `total_units` and `complete_units` to measures.
103+ fn migrate_v1 ( & mut self ) -> Result < ( ) > {
104+ let Some ( total_measures) = & mut self . measures else {
105+ bail ! ( "Missing measures in report" ) ;
106+ } ;
107+ for unit in & mut self . units {
108+ let Some ( measures) = & mut unit. measures else {
109+ bail ! ( "Missing measures in report unit" ) ;
110+ } ;
111+ let complete = unit. metadata . as_ref ( ) . and_then ( |m| m. complete ) . unwrap_or ( false ) as u32 ;
112+ let progress_categories =
113+ unit. metadata . as_ref ( ) . map ( |m| m. progress_categories . as_slice ( ) ) . unwrap_or ( & [ ] ) ;
114+ measures. total_units = 1 ;
115+ measures. complete_units = complete;
116+ total_measures. total_units += 1 ;
117+ total_measures. complete_units += complete;
118+ for id in progress_categories {
119+ if let Some ( category) = self . categories . iter_mut ( ) . find ( |c| & c. id == id) {
120+ let Some ( measures) = & mut category. measures else {
121+ bail ! ( "Missing measures in category" ) ;
122+ } ;
123+ measures. total_units += 1 ;
124+ measures. complete_units += complete;
125+ }
126+ }
127+ }
128+ self . version = 2 ;
129+ Ok ( ( ) )
130+ }
131+
132+ /// Calculate progress categories based on unit metadata.
91133 pub fn calculate_progress_categories ( & mut self ) {
92134 for unit in & self . units {
93135 let Some ( metadata) = unit. metadata . as_ref ( ) else {
@@ -242,6 +284,8 @@ impl AddAssign for Measures {
242284 self . matched_functions += other. matched_functions ;
243285 self . complete_code += other. complete_code ;
244286 self . complete_data += other. complete_data ;
287+ self . total_units += other. total_units ;
288+ self . complete_units += other. complete_units ;
245289 }
246290}
247291
0 commit comments