Skip to content

Design: 0.5 streams, utilities, and observability

Milestone: 0.5
Status: accepted with ADR-013–ADR-016

Goals

Complete the non-query high-level Rust surface for Redland workflow parity: document stream contracts, ship URI/file/Unicode/digest/vocab helpers, add World logging with optional tracing, and disposition hashes/lists as std replacements.

Stream policy (ADR-013)

Oxiland keeps three iterator shapes:

Surface Type Item
Model find StatementMatches Result<Quad>
Parser QuadStream / SliceStream Result<Quad>
Query QueryResults adapters solutions / triples / bool

Common contract:

  1. Streaming is lazy; no full materialization unless the caller collects.
  2. Early termination is by dropping the iterator (no required close callback).
  3. Errors surface as Result items or execute-time Error (not panics).
  4. No unifying trait in 0.5; document the shared policy instead.

Cancellation remains SPARQL-scoped (CancellationToken, ADR-012). Parse and bulk-load do not grow a wall-clock timeout API in 0.5.

Utility module

Public module oxiland::utility owns:

  • URI join / relativize helpers over validated IRIs
  • filename ↔ file:// URI heuristics
  • Unicode NFC/NFKC normalization helpers
  • digest algorithms (MD5, SHA-1, SHA-256) → bytes/hex
  • Namespace prefix ↔ base IRI helper
  • well-known vocabulary constants (RDF, RDFS, XSD, OWL, DC)

Malformed input returns Error::InvalidRdf, Error::Unsupported, or Error::Io—never panics.

Logging (ADR-014)

World gains:

  • LogLevel / LogFacility
  • callback registration (set_log_handler)
  • log emission with level filtering
  • optional Cargo feature tracing that also emits tracing events

Cloned World values share the same handler, minimum log level, and feature registry (same Arc pattern as features). Optional tracing emission uses that same minimum level.

Digests (ADR-015)

Closed algorithm set: Md5, Sha1, Sha256. Unknown names → Error::Unsupported. Always available in the default build (small crypto deps).

Hashes / lists (ADR-016)

Redland hash and list types are inventory not-applicable. Callers use HashMap, Vec, and Rust iterators. Migration examples document the mapping; Oxiland does not ship collection wrappers.

Evidence

  • Early-stop tests for find / parse / SELECT / CONSTRUCT
  • Utility unit tests + differential smoke harness
  • Logging ordering fixtures
  • Curated inventory redland-1.0.17-oxiland-0.5.json