///|
/// Render a machine-readable policy decision for CI systems.
pub fn PolicyResult::to_json(self : PolicyResult) -> String {
let violations = self.violations.map(violation => {
"{" +
"\"code\":" +
json_string(violation.code) +
"," +
"\"path\":" +
json_string(violation.path) +
"," +
"\"message\":" +
json_string(violation.message) +
"," +
"\"relatedChange\":" +
optional_json_string(violation.related_change) +
"}"
})
let allowed = self.allowed_breaking.map(change_reference_json)
let unallowed = self.unallowed_breaking.map(change_reference_json)
"{" +
"\"schemaVersion\":\"1.0\"," +
"\"kind\":\"evowitness-policy-result\"," +
"\"policy\":" +
json_string(self.policy_name) +
"," +
"\"passed\":" +
bool_json(self.passed()) +
"," +
"\"summary\":{" +
"\"violations\":" +
self.violations.length().to_string() +
"," +
"\"allowedBreaking\":" +
self.allowed_breaking.length().to_string() +
"," +
"\"unallowedBreaking\":" +
self.unallowed_breaking.length().to_string() +
"}," +
"\"violations\":[" +
violations.join(",") +
"]," +
"\"allowedBreaking\":[" +
allowed.join(",") +
"]," +
"\"unallowedBreaking\":[" +
unallowed.join(",") +
"]}"
}
///|
/// Render a migration plan for automation, ticket generation or dashboards.
pub fn MigrationPlan::to_json(self : MigrationPlan) -> String {
let steps = self.steps.map(step => {
let codes = step.related_codes.map(json_string)
"{" +
"\"id\":" +
json_string(step.id) +
"," +
"\"phase\":" +
json_string(step.phase.render()) +
"," +
"\"path\":" +
json_string(step.path) +
"," +
"\"action\":" +
json_string(step.action) +
"," +
"\"verification\":" +
json_string(step.verification) +
"," +
"\"relatedCodes\":[" +
codes.join(",") +
"]}"
})
"{" +
"\"schemaVersion\":\"1.0\"," +
"\"kind\":\"evowitness-migration-plan\"," +
"\"contract\":" +
json_string(self.contract_name) +
"," +
"\"fromVersion\":" +
json_string(self.from_version) +
"," +
"\"toVersion\":" +
json_string(self.to_version) +
"," +
"\"risk\":" +
json_string(self.risk) +
"," +
"\"steps\":[" +
steps.join(",") +
"]}"
}
///|
fn change_reference_json(change : Change) -> String {
"{" +
"\"code\":" +
json_string(change.code) +
"," +
"\"direction\":" +
json_string(change.direction) +
"," +
"\"path\":" +
json_string(change.path) +
"}"
}
///|
fn optional_json_string(value : String?) -> String {
match value {
Some(text) => json_string(text)
None => "null"
}
}
///|
fn bool_json(value : Bool) -> String {
if value {
"true"
} else {
"false"
}
}