///|
/// Hard, objectively verifiable semantic issue.
pub(all) enum ValidationIssueKind {
InvalidTypeUri
InvalidInstanceUri
InvalidStatusCode
} derive(Eq, Debug)
///|
pub struct ValidationIssue {
kind : ValidationIssueKind
context : String
} derive(Eq, Debug)
///|
pub fn ValidationIssue::kind(self : ValidationIssue) -> ValidationIssueKind {
self.kind
}
///|
pub fn ValidationIssue::context(self : ValidationIssue) -> String {
self.context
}
///|
pub fn ValidationIssueKind::name(self : ValidationIssueKind) -> String {
match self {
InvalidTypeUri => "InvalidTypeUri"
InvalidInstanceUri => "InvalidInstanceUri"
InvalidStatusCode => "InvalidStatusCode"
}
}
///|
/// Validate semantic constraints separately from parsing and audit advice.
pub fn validate_problem(problem : ProblemDetails) -> Array[ValidationIssue] {
let issues : Array[ValidationIssue] = []
match problem.type_raw() {
Some(value) =>
match validate_uri_reference(value) {
Err(error) =>
issues.push({ kind: InvalidTypeUri, context: error.context() })
Ok(_) => ()
}
None => ()
}
match problem.instance() {
Some(value) =>
match validate_uri_reference(value) {
Err(error) =>
issues.push({ kind: InvalidInstanceUri, context: error.context() })
Ok(_) => ()
}
None => ()
}
match problem.status() {
Some(code) if !is_valid_http_status(code) =>
issues.push({
kind: InvalidStatusCode,
context: "status must be between 100 and 599",
})
_ => ()
}
issues
}
///|
pub fn is_valid_problem(problem : ProblemDetails) -> Bool {
validate_problem(problem).is_empty()
}