moon-problem-details

RFC 9457 Problem Details JSON parser, serializer, validator, registry and audit toolkit for MoonBit.

problem-details
rfc9457
http
api
json
error
moonbit
moon add 6P66006/moon-problem-details@0.1.0
Download zip
Author
Version
0.1.0
License
Apache-2.0
Last updated
5 hours ago
Downloads
3
README

#moon-problem-details

Module: 6P66006/moon-problem-details Version: 0.1.0 Status: public mature MVP Repository: https://github.com/6P66006/moon-problem-details Maintainer: 崔瑞豪 (6P66006)

#Overview

moon-problem-details is an offline MoonBit toolkit for RFC 9457 Problem Details JSON. It parses, preserves, builds, validates, canonicalizes, audits and queries registered HTTP problem types without sending HTTP requests or dereferencing URIs.

#Install

moon add 6P66006/moon-problem-details

Import the package with a stable alias in moon.pkg:

import {
"6P66006/moon-problem-details" @problem,
}

#Quick start

Check the package and run the parsing example from the repository root:

moon check --target wasm-gc moon run ./examples/parse --target wasm-gc

For a complete cross-target verification, including tests and CLI smoke checks, run ./scripts/verify_all.ps1.

#Why Problem Details

Problem Details gives HTTP APIs a shared error-document shape while allowing each problem type to define extension members. This library keeps transport status separate: the JSON status member is advisory and never replaces the actual HTTP response status.

#RFC 9457 scope

The mature local MVP covers application/problem+json, the five standard members, extension members, about:blank, URI-reference syntax checks, deterministic serialization, HTTP response context checking, resource limits, structured errors and an offline IANA registry. RFC 9457, which obsoletes RFC 7807, is the implementation target.

#Problem model

ProblemDetails keeps type, title, status, detail and instance optional exactly as received. effective_type() returns about:blank when raw type is absent without modifying the parsed model.

#Parsing

Use parse_problem_json for text or parse_problem_json_bytes for raw UTF-8. MoonBit core parses JSON. A malformed JSON document or non-object root is a structured error. A standard member with the wrong JSON type is ignored and reported in ProblemParseResult.diagnostics, so other members continue to parse as RFC 9457 requires.

#Standard and extension members

Unknown object members are preserved as arbitrary Json values, including strings, numbers, booleans, nulls, arrays and objects. extension, extensions and has_extension query them. Builder extensions cannot collide with standard member names.

#about:blank

Missing type has the effective value about:blank. is_about_blank handles both missing and explicit forms. A nonstandard title for about:blank is an audit warning only because localization is permitted.

#Validation and HTTP context

validate_problem checks URI-reference syntax and the HTTP status range. validate_context checks application/problem+json, status mismatch and whether relative type or instance values have an absolute base URI. The caller supplies context; the library has no server or client.

#Building and serialization

ProblemBuilder::new() supports fluent standard members and arbitrary JSON extensions. problem(status, title) and about_blank(status) are conveniences. serialize_problem emits standard members in type, title, status, detail, instance order and top-level extensions in code-unit lexical order. Object order has no JSON semantics; ordering exists only for reproducibility.

#IANA registry

The vendored official HTTP Problem Types CSV is queried through is_registered_problem_type, lookup_problem_type and registered_problem_types. Runtime operation is entirely offline. The refresh script contacts IANA only with explicit --refresh; verification checks SHA-256, record count and generated data freshness.

Verify the committed snapshot without network access:

python ./scripts/verify_iana_snapshot.py

Maintainers may explicitly download a newer official CSV with python ./scripts/import_iana_problem_types.py --refresh. After reviewing the registry changes, regenerate generated_problem_types.mbt, update the recorded metadata and rerun the offline verifier. Normal builds, tests and CLI commands never invoke the refresh path.

#Audit and security

audit_problem reports advisory findings such as relative URIs, suspicious extension names, missing members, overlong text and debug-looking names. It is heuristic, not a sensitive-data detector. Do not put passwords, tokens, secrets, stack traces, SQL, server paths, internal hosts or private user data in titles, details or extensions.

#CLI

problem-tool provides exactly these commands: parse, validate, canonicalize, make, registry, audit, stats, batch, plus version and help. All commands are offline and emit deterministic JSON where practical.

moon run ./cmd/problem-tool -- parse --input '{"status":404}' moon run ./cmd/problem-tool -- validate --status 404 --input '{"status":404}' moon run ./cmd/problem-tool -- registry about:blank moon run ./cmd/problem-tool -- make --status 404 --title "Not Found" moon run ./cmd/problem-tool -- batch --input '{"title":"Not Found","status":404}' --input '{"status":500}'

Wrongly typed standard members are ignored with diagnostics instead of aborting the document:

moon run ./cmd/problem-tool -- parse --input '{"title":123,"status":404,"request_id":"abc"}'

The result retains status and request_id, omits the invalid title, and reports one diagnostic.

#Batch quality gates

analyze_problem_batch processes independent documents without retaining their original JSON strings in the aggregate report. It counts parse failures, non-fatal member diagnostics, semantic violations, audit warnings, effective problem types, IANA registrations, status classes and extension usage, then returns an accept, review or reject decision. ProblemBatchPolicy::strict() is suitable for CI, while the default and permissive policies support migration and offline inspection.

#Examples and testing

Five executable examples under examples/ demonstrate parsing, building, validation, audit and batch governance. Tests cover RFC-style fixtures, wrong-type member behavior, extensions, limits, the registry, batch policies, 800 deterministic property cases and every byte prefix of complex UTF-8 documents. Run the fail-fast gate with:

.\scripts\verify_all.ps1

It formats, checks, builds and tests wasm, wasm-gc, JS and native with warnings denied; smoke-tests every CLI command and example; verifies the snapshot; counts code; and lists the package. The suite contains 165 named tests on each target.

#Limitations

No application/problem+xml, XML, HTTP server/client, automatic URI dereference, full RFC 3986 resolver, JSON Schema, OpenAPI, exception framework or sensitive-data guarantee. See docs/limitations.md.

#License and local development status

Apache-2.0. The source repository is public on GitHub. Stable version 0.1.0 is prepared for the Mooncakes module 6P66006/moon-problem-details.

#
ProblemError

pub(all) suberror ProblemError {
ProblemError(ProblemErrorStage, ProblemErrorKind, String, Int?)
}

A structured error. JSON parser offsets are not invented when unavailable.

#
ProblemError::byte_offset

fn ProblemError::byte_offset(self : ProblemError) -> Int?

#
ProblemError::context

fn ProblemError::context(self : ProblemError) -> String

#
ProblemError::kind

#
ProblemError::stage

#
ProblemError::to_string

fn ProblemError::to_string(self : ProblemError) -> String

#
AuditIssue

pub struct AuditIssue {
kind : AuditIssueKind
severity : AuditSeverity
context : String
} derive(Eq,
Debug
)

#
AuditIssue::context

fn AuditIssue::context(self : AuditIssue) -> String

#
AuditIssue::kind

#
AuditIssue::severity

fn AuditIssue::severity(self : AuditIssue) -> AuditSeverity

#
AuditIssueKind

pub(all) enum AuditIssueKind {
RelativeTypeUri
RelativeInstanceUri
SuspiciousExtensionName
OverlongTitle
OverlongDetail
AboutBlankTitleMismatch
MissingTitle
MissingStatus
SensitiveLookingExtension
DebugInformationRisk
} derive(Eq,
Debug
)

Audit advice and heuristics; these are not parser errors.

#
AuditIssueKind::name

fn AuditIssueKind::name(self : AuditIssueKind) -> String

#
AuditReport

pub struct AuditReport {
issues : Array[AuditIssue]
} derive(Eq,
Debug
)

#
AuditReport::is_clean

fn AuditReport::is_clean(self : AuditReport) -> Bool

#
AuditReport::issues

fn AuditReport::issues(self : AuditReport) -> Array[AuditIssue]

#
AuditSeverity

pub(all) enum AuditSeverity {
Info
Warning
} derive(Eq,
Debug
)

#
BatchDecision

pub(all) enum BatchDecision {
Accept
Review
Reject
} derive(Eq,
Debug
)

Final decision for a batch of RFC 9457 documents.

#
BatchDecision::name

fn BatchDecision::name(self : BatchDecision) -> String

#
BatchFinding

pub struct BatchFinding {
document_index : Int
kind : BatchFindingKind
context : String
}

One finding tied to a document index. Batch-wide findings use index -1.

#
BatchFinding::context

fn BatchFinding::context(self : BatchFinding) -> String

#
BatchFinding::document_index

fn BatchFinding::document_index(self : BatchFinding) -> Int

#
BatchFinding::kind

#
BatchFindingKind

pub(all) enum BatchFindingKind {
DocumentLimitExceeded
ParseFailure
ParseDiagnostic
SemanticViolation
AuditWarning
RelativeProblemType
UnregisteredProblemType
MissingRequiredTitle
MissingRequiredStatus
} derive(Eq,
Debug
)

Machine-readable categories emitted while analyzing a batch.

#
BatchFindingKind::name

fn BatchFindingKind::name(self : BatchFindingKind) -> String

#
ContextIssue

pub struct ContextIssue {
kind : ContextIssueKind
context : String
} derive(Eq,
Debug
)

#
ContextIssue::context

fn ContextIssue::context(self : ContextIssue) -> String

#
ContextIssue::kind

#
ContextIssueKind

pub(all) enum ContextIssueKind {
InvalidContentType
StatusMismatch
MissingBaseUri
InvalidBaseUri
} derive(Eq,
Debug
)

#
ContextIssueKind::name

fn ContextIssueKind::name(self : ContextIssueKind) -> String

#
ExtensionFrequency

pub struct ExtensionFrequency {
name : String
count : Int
}

Frequency of one extension member name across parsed documents.

#
ExtensionFrequency::count

fn ExtensionFrequency::count(self : ExtensionFrequency) -> Int

#
ExtensionFrequency::name

fn ExtensionFrequency::name(self : ExtensionFrequency) -> String

#
ExtensionMember

pub struct ExtensionMember {
name : String
value : Json
} derive(Eq,
Debug
)

One extension member. Its value is any JSON value, without coercion.

#
ExtensionMember::name

fn ExtensionMember::name(self : ExtensionMember) -> String

#
ExtensionMember::value

fn ExtensionMember::value(self : ExtensionMember) -> Json

#
Limits

pub struct Limits {
max_input_bytes : Int
max_members : Int
max_extension_members : Int
max_string_bytes : Int
max_title_bytes : Int
max_detail_bytes : Int
max_nesting_depth : Int
} derive(Eq,
Debug
)

Parser and traversal resource limits.

#
Limits::default

fn Limits::default() -> Limits

#
Limits::max_detail_bytes

fn Limits::max_detail_bytes(self : Limits) -> Int

#
Limits::max_extension_members

fn Limits::max_extension_members(self : Limits) -> Int

#
Limits::max_input_bytes

fn Limits::max_input_bytes(self : Limits) -> Int

#
Limits::max_members

fn Limits::max_members(self : Limits) -> Int

#
Limits::max_nesting_depth

fn Limits::max_nesting_depth(self : Limits) -> Int

#
Limits::max_string_bytes

fn Limits::max_string_bytes(self : Limits) -> Int

#
Limits::max_title_bytes

fn Limits::max_title_bytes(self : Limits) -> Int

#
Limits::permissive

fn Limits::permissive() -> Limits

#
Limits::strict

fn Limits::strict() -> Limits

#
ProblemBatchPolicy

pub struct ProblemBatchPolicy {
max_documents : Int
max_parse_failures : Int
max_semantic_issues : Int
max_audit_issues : Int
max_unregistered_types : Int
require_title : Bool
require_status : Bool
allow_relative_types : Bool
}

Quality gate budgets for batch analysis.

#
ProblemBatchPolicy::allows_relative_types

fn ProblemBatchPolicy::allows_relative_types(self : ProblemBatchPolicy) -> Bool

#
ProblemBatchPolicy::default

Practical defaults: malformed or semantically invalid documents reject; advisory findings remain reviewable within a bounded budget.

#
ProblemBatchPolicy::max_audit_issues

fn ProblemBatchPolicy::max_audit_issues(self : ProblemBatchPolicy) -> Int

#
ProblemBatchPolicy::max_documents

fn ProblemBatchPolicy::max_documents(self : ProblemBatchPolicy) -> Int

#
ProblemBatchPolicy::max_parse_failures

fn ProblemBatchPolicy::max_parse_failures(self : ProblemBatchPolicy) -> Int

#
ProblemBatchPolicy::max_semantic_issues

fn ProblemBatchPolicy::max_semantic_issues(self : ProblemBatchPolicy) -> Int

#
ProblemBatchPolicy::max_unregistered_types

fn ProblemBatchPolicy::max_unregistered_types(self : ProblemBatchPolicy) -> Int

#
ProblemBatchPolicy::permissive

Permissive inspection policy that records findings without rejecting them.

#
ProblemBatchPolicy::requires_status

fn ProblemBatchPolicy::requires_status(self : ProblemBatchPolicy) -> Bool

#
ProblemBatchPolicy::requires_title

fn ProblemBatchPolicy::requires_title(self : ProblemBatchPolicy) -> Bool

#
ProblemBatchPolicy::strict

Strict CI policy for interoperable, registry-backed API error documents.

#
ProblemBatchPolicy::with_allow_relative_types

fn ProblemBatchPolicy::with_allow_relative_types(self : ProblemBatchPolicy, value : Bool) -> ProblemBatchPolicy

#
ProblemBatchPolicy::with_max_audit_issues

fn ProblemBatchPolicy::with_max_audit_issues(self : ProblemBatchPolicy, value : Int) -> ProblemBatchPolicy

#
ProblemBatchPolicy::with_max_documents

fn ProblemBatchPolicy::with_max_documents(self : ProblemBatchPolicy, value : Int) -> ProblemBatchPolicy

#
ProblemBatchPolicy::with_max_parse_failures

fn ProblemBatchPolicy::with_max_parse_failures(self : ProblemBatchPolicy, value : Int) -> ProblemBatchPolicy

#
ProblemBatchPolicy::with_max_semantic_issues

fn ProblemBatchPolicy::with_max_semantic_issues(self : ProblemBatchPolicy, value : Int) -> ProblemBatchPolicy

#
ProblemBatchPolicy::with_max_unregistered_types

fn ProblemBatchPolicy::with_max_unregistered_types(self : ProblemBatchPolicy, value : Int) -> ProblemBatchPolicy

#
ProblemBatchPolicy::with_require_status

fn ProblemBatchPolicy::with_require_status(self : ProblemBatchPolicy, value : Bool) -> ProblemBatchPolicy

#
ProblemBatchPolicy::with_require_title

fn ProblemBatchPolicy::with_require_title(self : ProblemBatchPolicy, value : Bool) -> ProblemBatchPolicy

#
ProblemBatchReport

pub struct ProblemBatchReport {
input_count : Int
parsed_count : Int
parse_failure_count : Int
diagnostic_count : Int
semantic_issue_count : Int
audit_issue_count : Int
about_blank_count : Int
registered_type_count : Int
unregistered_type_count : Int
relative_type_count : Int
missing_title_count : Int
missing_status_count : Int
total_member_count : Int
max_member_count : Int
informational_status_count : Int
successful_status_count : Int
redirection_status_count : Int
client_error_status_count : Int
server_error_status_count : Int
other_status_count : Int
type_frequencies : Array[ProblemTypeFrequency]
status_frequencies : Array[ProblemStatusFrequency]
extension_frequencies : Array[ExtensionFrequency]
findings : Array[BatchFinding]
decision : BatchDecision
quality_score : Int
}

Aggregate, deterministic evidence for a collection of problem documents.

#
ProblemBatchReport::about_blank_count

fn ProblemBatchReport::about_blank_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::audit_issue_count

fn ProblemBatchReport::audit_issue_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::average_member_count

fn ProblemBatchReport::average_member_count(self : ProblemBatchReport) -> Double

#
ProblemBatchReport::client_error_status_count

fn ProblemBatchReport::client_error_status_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::decision

#
ProblemBatchReport::diagnostic_count

fn ProblemBatchReport::diagnostic_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::extension_frequencies

fn ProblemBatchReport::extension_frequencies(self : ProblemBatchReport) -> Array[ExtensionFrequency]

#
ProblemBatchReport::findings

#
ProblemBatchReport::informational_status_count

fn ProblemBatchReport::informational_status_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::input_count

fn ProblemBatchReport::input_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::is_accepted

fn ProblemBatchReport::is_accepted(self : ProblemBatchReport) -> Bool

#
ProblemBatchReport::max_member_count

fn ProblemBatchReport::max_member_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::missing_status_count

fn ProblemBatchReport::missing_status_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::missing_title_count

fn ProblemBatchReport::missing_title_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::other_status_count

fn ProblemBatchReport::other_status_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::parse_failure_count

fn ProblemBatchReport::parse_failure_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::parsed_count

fn ProblemBatchReport::parsed_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::quality_score

fn ProblemBatchReport::quality_score(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::redirection_status_count

fn ProblemBatchReport::redirection_status_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::registered_type_count

fn ProblemBatchReport::registered_type_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::relative_type_count

fn ProblemBatchReport::relative_type_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::semantic_issue_count

fn ProblemBatchReport::semantic_issue_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::server_error_status_count

fn ProblemBatchReport::server_error_status_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::status_frequencies

#
ProblemBatchReport::successful_status_count

fn ProblemBatchReport::successful_status_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::summary_json

fn ProblemBatchReport::summary_json(self : ProblemBatchReport) -> String

Compact deterministic JSON suitable for CI logs.

#
ProblemBatchReport::total_member_count

fn ProblemBatchReport::total_member_count(self : ProblemBatchReport) -> Int

#
ProblemBatchReport::type_frequencies

#
ProblemBatchReport::unregistered_type_count

fn ProblemBatchReport::unregistered_type_count(self : ProblemBatchReport) -> Int

#
ProblemBuilder

pub struct ProblemBuilder {
type_raw : String?
title : String?
status : Int?
detail : String?
instance : String?
extensions : Array[ExtensionMember]
error : ProblemError?
}

Mutable fluent builder. Build returns a structured error on invalid state.

#
ProblemBuilder::build

#
ProblemBuilder::detail

fn ProblemBuilder::detail(self : ProblemBuilder, value : String) -> ProblemBuilder

#
ProblemBuilder::extension

fn ProblemBuilder::extension(self : ProblemBuilder, name : String, value : Json) -> ProblemBuilder

#
ProblemBuilder::instance

fn ProblemBuilder::instance(self : ProblemBuilder, value : String) -> ProblemBuilder

#
ProblemBuilder::new

#
ProblemBuilder::status

fn ProblemBuilder::status(self : ProblemBuilder, value : Int) -> ProblemBuilder

#
ProblemBuilder::title

fn ProblemBuilder::title(self : ProblemBuilder, value : String) -> ProblemBuilder

#
ProblemBuilder::type_uri

fn ProblemBuilder::type_uri(self : ProblemBuilder, value : String) -> ProblemBuilder

#
ProblemContext

pub struct ProblemContext {
actual_status : Int?
content_type : String?
base_uri : String?
} derive(Eq,
Debug
)

HTTP response metadata supplied by the caller; this library sends no HTTP.

#
ProblemDetails

pub struct ProblemDetails {
type_raw : String?
title : String?
status : Int?
detail : String?
instance : String?
extensions : Array[ExtensionMember]
} derive(Eq,
Debug
)

RFC 9457 Problem Details data model. Missing members remain missing.

#
ProblemDetails::detail

fn ProblemDetails::detail(self : ProblemDetails) -> String?

#
ProblemDetails::effective_type

fn ProblemDetails::effective_type(self : ProblemDetails) -> String

Missing type is semantically about:blank; parsing does not insert it.

#
ProblemDetails::extension

fn ProblemDetails::extension(self : ProblemDetails, name : String) -> Json?

#
ProblemDetails::extensions

#
ProblemDetails::has_extension

fn ProblemDetails::has_extension(self : ProblemDetails, name : String) -> Bool

#
ProblemDetails::instance

fn ProblemDetails::instance(self : ProblemDetails) -> String?

#
ProblemDetails::is_about_blank

fn ProblemDetails::is_about_blank(self : ProblemDetails) -> Bool

#
ProblemDetails::member_count

fn ProblemDetails::member_count(self : ProblemDetails) -> Int

#
ProblemDetails::standard_member_count

fn ProblemDetails::standard_member_count(self : ProblemDetails) -> Int

#
ProblemDetails::status

fn ProblemDetails::status(self : ProblemDetails) -> Int?

#
ProblemDetails::title

fn ProblemDetails::title(self : ProblemDetails) -> String?

#
ProblemDetails::type_raw

fn ProblemDetails::type_raw(self : ProblemDetails) -> String?

#
ProblemDiagnostic

pub struct ProblemDiagnostic {
kind : ProblemDiagnosticKind
member_name : String
expected : String
actual : String
} derive(Eq,
Debug
)

#
ProblemDiagnostic::actual

fn ProblemDiagnostic::actual(self : ProblemDiagnostic) -> String

#
ProblemDiagnostic::expected

fn ProblemDiagnostic::expected(self : ProblemDiagnostic) -> String

#
ProblemDiagnostic::kind

#
ProblemDiagnostic::member_name

fn ProblemDiagnostic::member_name(self : ProblemDiagnostic) -> String

#
ProblemDiagnosticKind

pub(all) enum ProblemDiagnosticKind {
IgnoredMemberWrongType
} derive(Eq,
Debug
)

Non-fatal interpretation diagnostic required by RFC 9457 consumer semantics.

#
ProblemErrorKind

pub(all) enum ProblemErrorKind {
InvalidJson
InvalidUtf8
RootNotObject
InvalidUriReference
InvalidPercentEncoding
InvalidStatus
DuplicateReservedExtension
LimitExceeded
InvalidBuilderState
} derive(Eq,
Debug
)

Machine-readable error category.

#
ProblemErrorKind::name

fn ProblemErrorKind::name(self : ProblemErrorKind) -> String

#
ProblemErrorStage

pub(all) enum ProblemErrorStage {
Input
Json
Member
Uri
Status
Limit
Registry
Builder
Context
} derive(Eq,
Debug
)

Structured processing stage for errors.

#
ProblemErrorStage::name

fn ProblemErrorStage::name(self : ProblemErrorStage) -> String

#
ProblemParseResult

pub struct ProblemParseResult {
problem : ProblemDetails
diagnostics : Array[ProblemDiagnostic]
} derive(Eq,
Debug
)

Successful parse plus non-fatal diagnostics.

#
ProblemParseResult::diagnostics

#
ProblemParseResult::problem

#
ProblemStatusFrequency

pub struct ProblemStatusFrequency {
status : Int?
count : Int
}

Frequency of one declared HTTP status. None represents a missing status.

#
ProblemStatusFrequency::count

#
ProblemStatusFrequency::status

#
ProblemTypeFrequency

pub struct ProblemTypeFrequency {
type_uri : String
count : Int
}

Frequency of one effective problem type URI.

#
ProblemTypeFrequency::count

#
ProblemTypeFrequency::type_uri

fn ProblemTypeFrequency::type_uri(self : ProblemTypeFrequency) -> String

#
ProblemTypeRecord

pub struct ProblemTypeRecord {
type_uri : String
title : String
recommended_status : Int?
reference : String
} derive(Eq,
Debug
)

One offline IANA HTTP Problem Types registration.

#
ProblemTypeRecord::recommended_status

fn ProblemTypeRecord::recommended_status(self : ProblemTypeRecord) -> Int?

#
ProblemTypeRecord::reference

fn ProblemTypeRecord::reference(self : ProblemTypeRecord) -> String

#
ProblemTypeRecord::title

fn ProblemTypeRecord::title(self : ProblemTypeRecord) -> String

#
ProblemTypeRecord::type_uri

fn ProblemTypeRecord::type_uri(self : ProblemTypeRecord) -> String

#
UriReferenceInfo

pub struct UriReferenceInfo {
absolute : Bool
relative : Bool
} derive(Eq,
Debug
)

Result of the intentionally small RFC 3986 URI-reference syntax check.

#
UriReferenceInfo::is_absolute

fn UriReferenceInfo::is_absolute(self : UriReferenceInfo) -> Bool

#
UriReferenceInfo::is_relative

fn UriReferenceInfo::is_relative(self : UriReferenceInfo) -> Bool

#
ValidationIssue

pub struct ValidationIssue {
kind : ValidationIssueKind
context : String
} derive(Eq,
Debug
)

#
ValidationIssue::context

fn ValidationIssue::context(self : ValidationIssue) -> String

#
ValidationIssue::kind

#
ValidationIssueKind

pub(all) enum ValidationIssueKind {
InvalidTypeUri
InvalidInstanceUri
InvalidStatusCode
} derive(Eq,
Debug
)

Hard, objectively verifiable semantic issue.

#
ValidationIssueKind::name

fn ValidationIssueKind::name(self : ValidationIssueKind) -> String

#
about_blank

fn about_blank(status : Int) -> Result[ProblemDetails, ProblemError]

#
analyze_problem_batch

fn analyze_problem_batch(inputs : Array[String], policy? : ProblemBatchPolicy, limits? : Limits) -> ProblemBatchReport

Analyze documents independently, preserve deterministic input order, and return aggregate evidence without retaining the original JSON strings.

#
audit_problem

fn audit_problem(problem : ProblemDetails) -> AuditReport

Heuristic security and interoperability audit. It makes no leak-detection guarantee.

#
canonicalize_problem_json

fn canonicalize_problem_json(input : String) -> Result[String, ProblemError]

#
extension_member

fn extension_member(name : String, value : Json) -> ExtensionMember

#
is_absolute_uri_reference

fn is_absolute_uri_reference(value : String) -> Bool

#
is_registered_problem_type

fn is_registered_problem_type(uri : String) -> Bool

#
is_valid_http_status

fn is_valid_http_status(code : Int) -> Bool

#
is_valid_problem

fn is_valid_problem(problem : ProblemDetails) -> Bool

#
library_version

fn library_version() -> String

#
lookup_problem_type

fn lookup_problem_type(uri : String) -> ProblemTypeRecord?

#
parse_problem

fn parse_problem(input : String) -> Result[ProblemDetails, ProblemError]

Convenience API preserving errors while discarding diagnostics.

#
parse_problem_json

fn parse_problem_json(input : String) -> Result[ProblemParseResult, ProblemError]

#
parse_problem_json_bytes

fn parse_problem_json_bytes(input : Bytes, limits? : Limits) -> Result[ProblemParseResult, ProblemError]

Byte-oriented entry point for network payloads and truncation testing.

#
parse_problem_json_with_limits

fn parse_problem_json_with_limits(input : String, limits : Limits) -> Result[ProblemParseResult, ProblemError]

Parse JSON using core's parser, then interpret RFC 9457 members.

#
problem

fn problem(status : Int, title : String) -> Result[ProblemDetails, ProblemError]

#
problem_context

fn problem_context(actual_status : Int?, content_type : String?, base_uri : String?) -> ProblemContext

#
problem_details

fn problem_details(type_raw : String?, title : String?, status : Int?, detail : String?, instance : String?, extensions : Array[ExtensionMember]) -> ProblemDetails

#
problem_error

fn problem_error(stage : ProblemErrorStage, kind : ProblemErrorKind, context : String, byte_offset? : Int) -> ProblemError

#
problem_media_type

fn problem_media_type() -> String

#
problem_type_record

fn problem_type_record(type_uri : String, title : String, recommended_status : Int?, reference : String) -> ProblemTypeRecord

#
registered_problem_types

fn registered_problem_types() -> Array[ProblemTypeRecord]

#
registry_snapshot_date

fn registry_snapshot_date() -> String

#
registry_snapshot_sha256

fn registry_snapshot_sha256() -> String

#
serialize_problem

fn serialize_problem(problem : ProblemDetails) -> String

Deterministic top-level serializer: RFC members first, extensions sorted.

#
status_reason

fn status_reason(code : Int) -> String?

Common HTTP reason phrases. Unknown valid status codes return None.

#
validate_context

fn validate_context(problem : ProblemDetails, context : ProblemContext) -> Array[ContextIssue]

#
validate_problem

fn validate_problem(problem : ProblemDetails) -> Array[ValidationIssue]

Validate semantic constraints separately from parsing and audit advice.

#
validate_uri_reference

fn validate_uri_reference(value : String) -> Result[UriReferenceInfo, ProblemError]

Validate the syntax needed by RFC 9457 without resolving or dereferencing.