Skip to content

Milestone 0.2 — RDF input and output

Status: complete
Outcome: Redland-shaped, safe, stream-oriented RDF parsing and serialization
Depends on: 0.1 model/context semantics
Blocks: 0.3 query result serialization and dataset setup
Release evidence: docs/reports/0.2.md

This is the executable specification for 0.2. The roadmap defines the release outcome; this document defines the work packages, dependency order, acceptance cases, and decisions required to reach it.

User-visible result

At the end of 0.2, a Rust caller can:

  • choose a supported RDF syntax by canonical name, MIME type, or extension;
  • parse bytes, buffered readers, strings, and files with an optional base IRI;
  • stream parsed quads into a caller or model with defined graph semantics;
  • serialize a graph or dataset to a writer, string, or file;
  • configure namespaces where the selected syntax supports them;
  • distinguish unsupported format, invalid configuration, I/O, parse, and serialization failures;
  • discover what the current build supports without trial-and-error;
  • consult a Redland mapping that explains supported names and deviations.

The existing oxiland::io::primitives re-exports remain available for advanced use, but they are not evidence for the 0.2 Redland-shaped facade. The public Parser / Serializer / Syntax types are the verified surface.

In scope

  • Turtle, N-Triples, N-Quads, TriG, and RDF/XML when Oxigraph 0.5.9 supports the required behavior;
  • deterministic format lookup and capability reporting;
  • Read/BufRead, Write, string/byte, and filesystem entry points;
  • base IRI handling;
  • default-graph versus named-graph destination policy;
  • parser blank-node scope;
  • serializer namespace configuration;
  • streaming and early termination;
  • source locations and stable public error categories;
  • applicable W3C manifests exercised through Oxiland's public facade;
  • Redland parser/serializer inventory slices and differential fixtures.

Non-goals

  • SPARQL result formats or graph query-result adapters (0.3);
  • SPARQL Update (0.3);
  • transactional or crash-atomic bulk import (0.4);
  • network fetching, URI dereferencing, content negotiation, or remote writes;
  • public custom parser/serializer registration before the factory strategy is decided;
  • exact byte-for-byte output unless a specific Redland formatting contract is being tested;
  • syntax support that Oxigraph cannot safely provide.

Required design decisions

No public facade implementation starts until these questions have a recorded answer:

ID Decision Why it blocks Output
D-02-01 Parser output and model-load atomicity determines iterator items and partial-failure behavior ADR-007
D-02-02 Format identity and discovery determines public names, aliases, and future extensibility ADR-008
D-02-03 Error context ownership determines whether paths, locations, and causes remain inspectable public error proposal
D-02-04 Graph target policy determines triple-to-quad mapping and named-graph preservation compatibility note + tests
D-02-05 Namespace configuration lifecycle determines builder mutability and serializer reuse API proposal

Decision prototypes may be private. Accepted public types must not depend on an unresolved custom-factory or transaction design.

Proposed API characteristics

The exact names are deliberately not frozen here. The design review should produce types with these properties:

  • a closed, inspectable supported-format value for built-in syntaxes;
  • parser and serializer builders whose configuration is validated before I/O;
  • reader/writer APIs generic over standard Rust I/O traits;
  • iterator or callback output that can stop early without reading the complete source;
  • explicit graph-target selection rather than an implicit default;
  • convenience methods for strings and files built on the streaming core;
  • errors that preserve category and useful source context;
  • capability queries separated from parsing attempts;
  • no public dependency on Fjall or storage implementation types.

Convenience methods may collect data only where their name and documentation make that cost clear.

Work package sequence

WP-02-00 — Baseline and inventory

Depends on: none

Deliverables:

  • pin Redland headers/manual and record Raptor/Rasqal build metadata;
  • generate or curate parser and serializer inventory entries;
  • upgrade the inventory schema where necessary to carry normalized signatures, ownership, deviations, and fixture evidence;
  • enumerate Redland format names, aliases, MIME types, and option URIs;
  • record Oxigraph 0.5.9 support and known upstream limitations;
  • create fixture directories and metadata schema;
  • establish a runnable native Redland oracle path for the I/O subset.

Acceptance:

  • every targeted Redland I/O symbol has a stable inventory ID;
  • each format/alias has one disposition: planned, unsupported with reason, or deferred with milestone;
  • the baseline source versions and checksums are reproducible;
  • the inventory validator rejects missing required metadata;
  • the oracle can emit a versioned result for one smoke fixture.

WP-02-01 — Design spikes and decisions

Depends on: WP-02-00

Deliverables:

  • minimal streaming parser and serializer prototypes;
  • measurements showing whether adapters buffer documents or statements;
  • ADR-007 and ADR-008 decisions;
  • public API proposal covering ownership, errors, graph targets, and namespaces.

Acceptance:

  • the proposal includes complete happy-path and failure-path examples;
  • early termination and partial input failure have defined behavior;
  • no open decision can force a breaking change to the proposed core types.

WP-02-02 — Format and capability layer

Depends on: WP-02-01

Deliverables:

  • canonical format representation;
  • lookup by Redland name, MIME type, and extension;
  • advertised read/write and graph/dataset capabilities;
  • explicit unsupported-format errors;
  • compatibility table for aliases and unsupported names.

Acceptance:

  • lookup is case and parameter aware according to documented rules;
  • ambiguous or unknown input does not silently choose a format;
  • table-driven tests cover every published name, MIME type, and extension;
  • capability output and actual parser/serializer availability cannot diverge.

WP-02-03 — Streaming parser

Depends on: WP-02-02

Deliverables:

  • reader and byte/string entry points;
  • optional validated base IRI;
  • fallible streaming quad output;
  • graph-target and blank-node-scope behavior;
  • structured parse diagnostics.

Acceptance:

  • a caller can stop after the first item without full materialization;
  • malformed input returns a parse error with available line/column or offset;
  • triple and dataset syntaxes follow the documented graph-target policy;
  • blank nodes do not collide across independent parse operations;
  • parser configuration errors occur before consuming input where practical.

WP-02-04 — Model loading and file input

Depends on: WP-02-03

Deliverables:

  • load-into-model convenience path;
  • filesystem entry points;
  • defined partial-load/atomicity behavior;
  • I/O versus syntax error preservation.

Acceptance:

  • existing model data is handled exactly as documented on parse failure;
  • paths are diagnostic context, not a source of format guessing unless the caller requests extension detection;
  • file handles close on all success and failure paths;
  • named-graph imports do not leak into the default graph.

WP-02-05 — Streaming serializer

Depends on: WP-02-02

Deliverables:

  • graph/dataset serialization to Write;
  • namespace configuration;
  • string/byte and filesystem convenience paths;
  • explicit incompatibility errors for graph-only versus dataset formats.

Acceptance:

  • writer failures remain distinguishable from RDF configuration failures;
  • dataset serialization preserves named/default graph membership;
  • namespace declarations are applied only where supported;
  • output is standards-valid for each advertised format;
  • large datasets are not first collected into a second full in-memory copy.

WP-02-06 — Conformance and differential evidence

Depends on: WP-02-03 through WP-02-05

Deliverables:

  • pinned applicable W3C syntax manifests;
  • native Redland I/O fixtures using normalized dataset comparison;
  • shared Oxiland/native runners that emit the common result schema;
  • formatting-specific fixtures where bytes are observable;
  • malformed, boundary, and Unicode corpus;
  • machine-readable results.

Acceptance:

  • all advertised syntax paths run through the public Oxiland API;
  • both runners complete from a documented clean setup;
  • every skip names an issue or accepted deviation and review milestone;
  • differential failures are classified, not overwritten with new goldens;
  • reports identify platform, features, dependency versions, and suite revision.

WP-02-07 — Documentation and release

Depends on: all prior packages

Deliverables:

  • parser and serializer guides with runnable examples;
  • Redland-to-Oxiland I/O migration table;
  • updated API snapshot, parity ledger, roadmap, risk register, and changelog;
  • docs/reports/0.2.md;
  • packaged-crate smoke test from a clean temporary project.

Acceptance:

  • examples cover reader/writer, file, base IRI, namespaces, named graphs, and failure handling;
  • all roadmap and verification gates link to durable evidence;
  • no public item lacks Rustdoc;
  • package contents include the required docs and fixtures/licenses;
  • the milestone has no triggered high-impact risk without tested mitigation.

Dependency map

WP-02-00 baseline
      |
      v
WP-02-01 decisions
      |
      v
WP-02-02 formats/capabilities
      |                 |
      v                 v
WP-02-03 parser     WP-02-05 serializer
      |
      v
WP-02-04 model/file input
      \                 /
       v               v
    WP-02-06 evidence
             |
             v
    WP-02-07 release

Parser and serializer implementation may proceed in parallel after the shared format layer is accepted. Evidence work starts with fixtures during WP-02-00; WP-02-06 is where the complete matrix becomes a release gate.

Minimum acceptance matrix

For each advertised syntax, record:

Case Parser Serializer Required assertion
empty input/model yes yes valid empty behavior
one triple yes yes semantic equality
named graph dataset formats dataset formats graph name preserved
base/relative IRI where supported where supported resolved output
language/datatype yes yes term metadata preserved
blank nodes yes yes graph-isomorphic result
Unicode yes yes scalar values preserved
malformed input yes n/a category and location
failing reader/writer yes yes I/O category preserved
large stream yes yes bounded adapter memory
early stop yes n/a source not fully consumed where possible

The actual matrix records pass, fail, skip, or not applicable, plus a reason for every non-pass.

Exit checklist

  • All required decisions are accepted.
  • Inventory slice is complete for the promised I/O scope.
  • Public facade and capability layer are documented.
  • Required syntaxes pass round-trip and malformed-input tests.
  • Applicable W3C and Redland differential fixtures are reported.
  • Large-input evidence supports the streaming claim.
  • Public API snapshot and migration notes are updated.
  • Packaged-crate smoke test passes on stable and MSRV.
  • Parity ledger links the exact inventory and suite revisions.
  • No 0.2 release blocker remains open.

Explicit deferrals

Item User impact Workaround Destination
N3 syntax Redland n3 factory unavailable Use Turtle when input is Turtle-compatible later 0.x if Oxigraph gains true N3 write
JSON-LD Redland jsonld factory unavailable External JSON-LD tooling later 0.x after streaming policy
Content sniffing (guess) No automatic format detection Explicit Syntax or extension detection APIs unsupported by design (ADR-008)
Transactional atomic import Progressive load can leave durable partial data load_collecting for parse-then-insert batching 0.4
Custom parser/serializer factories No public registration API Built-in Syntax table only later when factory strategy is decided

Any incomplete item moves to a later milestone only if the release still meets the stated 0.2 outcome. The deferral record must name user impact, workaround, owner workstream, destination milestone, and whether documentation or capability reporting prevents an accidental support claim.