@@ -8,9 +8,10 @@ use serde_json::error::Category;
8
8
include ! ( concat!( env!( "OUT_DIR" ) , "/objdiff.report.rs" ) ) ;
9
9
include ! ( concat!( env!( "OUT_DIR" ) , "/objdiff.report.serde.rs" ) ) ;
10
10
11
- pub const REPORT_VERSION : u32 = 1 ;
11
+ pub const REPORT_VERSION : u32 = 2 ;
12
12
13
13
impl Report {
14
+ /// Attempts to parse the report as binary protobuf or JSON.
14
15
pub fn parse ( data : & [ u8 ] ) -> Result < Self > {
15
16
if data. is_empty ( ) {
16
17
bail ! ( std:: io:: Error :: from( std:: io:: ErrorKind :: UnexpectedEof ) ) ;
@@ -25,6 +26,7 @@ impl Report {
25
26
Ok ( report)
26
27
}
27
28
29
+ /// Attempts to parse the report as JSON, migrating from the legacy report format if necessary.
28
30
fn from_json ( bytes : & [ u8 ] ) -> Result < Self , serde_json:: Error > {
29
31
match serde_json:: from_slice :: < Self > ( bytes) {
30
32
Ok ( report) => Ok ( report) ,
@@ -43,16 +45,23 @@ impl Report {
43
45
}
44
46
}
45
47
48
+ /// Migrates the report to the latest version.
49
+ /// Fails if the report version is newer than supported.
46
50
pub fn migrate ( & mut self ) -> Result < ( ) > {
47
51
if self . version == 0 {
48
52
self . migrate_v0 ( ) ?;
49
53
}
54
+ if self . version == 1 {
55
+ self . migrate_v1 ( ) ?;
56
+ }
50
57
if self . version != REPORT_VERSION {
51
58
bail ! ( "Unsupported report version: {}" , self . version) ;
52
59
}
53
60
Ok ( ( ) )
54
61
}
55
62
63
+ /// Adds `complete_code`, `complete_data`, `complete_code_percent`, and `complete_data_percent`
64
+ /// to measures, and sets `progress_categories` in unit metadata.
56
65
fn migrate_v0 ( & mut self ) -> Result < ( ) > {
57
66
let Some ( measures) = & mut self . measures else {
58
67
bail ! ( "Missing measures in report" ) ;
@@ -61,15 +70,16 @@ impl Report {
61
70
let Some ( unit_measures) = & mut unit. measures else {
62
71
bail ! ( "Missing measures in report unit" ) ;
63
72
} ;
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 ) ;
66
81
} ;
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 {
73
83
unit_measures. complete_code = unit_measures. total_code ;
74
84
unit_measures. complete_data = unit_measures. total_data ;
75
85
unit_measures. complete_code_percent = 100.0 ;
@@ -84,10 +94,42 @@ impl Report {
84
94
measures. complete_data += unit_measures. complete_data ;
85
95
}
86
96
measures. calc_matched_percent ( ) ;
97
+ self . calculate_progress_categories ( ) ;
87
98
self . version = 1 ;
88
99
Ok ( ( ) )
89
100
}
90
101
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.
91
133
pub fn calculate_progress_categories ( & mut self ) {
92
134
for unit in & self . units {
93
135
let Some ( metadata) = unit. metadata . as_ref ( ) else {
@@ -242,6 +284,8 @@ impl AddAssign for Measures {
242
284
self . matched_functions += other. matched_functions ;
243
285
self . complete_code += other. complete_code ;
244
286
self . complete_data += other. complete_data ;
287
+ self . total_units += other. total_units ;
288
+ self . complete_units += other. complete_units ;
245
289
}
246
290
}
247
291
0 commit comments