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.