///|
fn merge_rules(
left : ArrayView[SarifRule],
right : ArrayView[SarifRule],
) -> Array[SarifRule] {
let out = left.to_owned()
for rule in right {
if find_rule_by_id(out, rule.id) is None {
out.push(rule)
}
}
out
}
///|
fn merge_artifacts(
left : ArrayView[Artifact],
right : ArrayView[Artifact],
) -> Array[Artifact] {
let out = left.to_owned()
for artifact in right {
let mut found = false
for item in out {
if item.location.uri == artifact.location.uri {
found = true
}
}
if !found {
out.push(artifact)
}
}
out
}
///|
pub fn find_rule_by_id(
rules : ArrayView[SarifRule],
id : StringView,
) -> SarifRule? {
let needle = id.to_owned()
for rule in rules {
if rule.id == needle {
return Some(rule)
}
}
None
}
///|
pub fn SarifRun::merge_with(self : SarifRun, other : SarifRun) -> SarifRun {
let driver = {
..self.tool,
rules: merge_rules(self.tool.rules, other.tool.rules),
}
{
tool: driver,
results: self.results + other.results,
artifacts: merge_artifacts(self.artifacts, other.artifacts),
invocations: self.invocations + other.invocations,
automation_id: self.automation_id,
}
}
///|
pub fn merge_runs_by_tool(runs : ArrayView[SarifRun]) -> Array[SarifRun] {
let out : Array[SarifRun] = []
for run in runs {
let mut merged = false
for i, existing in out {
if existing.tool.name == run.tool.name {
out[i] = existing.merge_with(run)
merged = true
}
}
if !merged {
out.push(run)
}
}
out
}
///|
pub fn SarifLog::merge_with(self : SarifLog, other : SarifLog) -> SarifLog {
{ ..self, runs: merge_runs_by_tool(self.runs + other.runs) }
}
///|
pub fn merge_logs(logs : ArrayView[SarifLog]) -> SarifLog {
let runs : Array[SarifRun] = []
for log in logs {
for run in log.runs {
runs.push(run)
}
}
SarifLog::SarifLog(merge_runs_by_tool(runs))
}