Skip to content

Commit dbdda55

Browse files
committed
Add Report::split
A hack for supporting games that build all versions at once.
1 parent a43320a commit dbdda55

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

objdiff-core/src/bindings/report.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,72 @@ impl Report {
117117
measures.calc_matched_percent();
118118
}
119119
}
120+
121+
/// Split the report into multiple reports based on progress categories.
122+
/// Assumes progress categories are in the format `version`, `version.category`.
123+
/// This is a hack for projects that generate all versions in a single report.
124+
pub fn split(self) -> Vec<(String, Report)> {
125+
let mut reports = Vec::new();
126+
// Map units to Option to allow taking ownership
127+
let mut units = self.units.into_iter().map(Some).collect::<Vec<_>>();
128+
for category in &self.categories {
129+
if category.id.contains(".") {
130+
// Skip subcategories
131+
continue;
132+
}
133+
fn is_sub_category(id: &str, parent: &str, sep: char) -> bool {
134+
id.starts_with(parent)
135+
&& id.get(parent.len()..).map_or(false, |s| s.starts_with(sep))
136+
}
137+
let mut sub_categories = self
138+
.categories
139+
.iter()
140+
.filter(|c| is_sub_category(&c.id, &category.id, '.'))
141+
.cloned()
142+
.collect::<Vec<_>>();
143+
// Remove category prefix
144+
for sub_category in &mut sub_categories {
145+
sub_category.id = sub_category.id[category.id.len() + 1..].to_string();
146+
}
147+
let mut sub_units = units
148+
.iter_mut()
149+
.filter_map(|opt| {
150+
let unit = opt.as_mut()?;
151+
let metadata = unit.metadata.as_ref()?;
152+
if metadata.progress_categories.contains(&category.id) {
153+
opt.take()
154+
} else {
155+
None
156+
}
157+
})
158+
.collect::<Vec<_>>();
159+
for sub_unit in &mut sub_units {
160+
// Remove leading version/ from unit name
161+
if let Some(name) =
162+
sub_unit.name.strip_prefix(&category.id).and_then(|s| s.strip_prefix('/'))
163+
{
164+
sub_unit.name = name.to_string();
165+
}
166+
// Filter progress categories
167+
let Some(metadata) = sub_unit.metadata.as_mut() else {
168+
continue;
169+
};
170+
metadata.progress_categories = metadata
171+
.progress_categories
172+
.iter()
173+
.filter(|c| is_sub_category(c, &category.id, '.'))
174+
.map(|c| c[category.id.len() + 1..].to_string())
175+
.collect();
176+
}
177+
reports.push((category.id.clone(), Report {
178+
measures: category.measures,
179+
units: sub_units,
180+
version: self.version,
181+
categories: sub_categories,
182+
}));
183+
}
184+
reports
185+
}
120186
}
121187

122188
impl Measures {

0 commit comments

Comments
 (0)