oxirs-core 0.3.2

Core RDF and SPARQL functionality for OxiRS - native Rust implementation with zero dependencies
Documentation

OxiRS Core

Version docs.rs

Foundational, Rust-native RDF data model and SPARQL engine for the OxiRS semantic web platform

Status: v0.3.2 - Released 2026-07-11

Production Release: Production-ready with API stability guarantees. Semantic versioning enforced.

Overview

oxirs-core provides the foundational data structures and operations for working with RDF data in Rust. It is the base crate of the OxiRS workspace: every other oxirs-* crate (query engines, servers, storage backends, AI tooling) depends on it, while it depends on none of them — no other OxiRS crate sits underneath it. Originally extracted from OxiGraph's RDF implementation, it has since grown a large surface of its own — SPARQL algebra/execution, persistent storage, federation, indexing, and enterprise compliance tooling — while retaining an OxiGraph-compatible core (oxigraph_compat) for easy migration.

Features

Core RDF Data Model

  • Named nodes (IRIs): NamedNode, RFC 3987-oriented IRI validation
  • Blank nodes: BlankNode, scoped identifiers
  • Literals: Literal, typed/language-tagged strings with XSD datatype support
  • Variables: Variable, SPARQL query variables
  • Triples/Quads: Triple / Quad, full RDF 1.2 model with named-graph support
  • RDF-star: quoted triples / statement reification (rdf-star feature, on by default)

SPARQL Foundation

  • SPARQL 1.1/1.2 query: SELECT, CONSTRUCT, ASK, DESCRIBE (query, sparql modules — parser, cost-based planner, streaming executor)
  • SPARQL 1.1 update: INSERT/DELETE DATA, LOAD, CLEAR
  • Federation: SERVICE-clause execution against remote SPARQL endpoints (federation)
  • Built-in functions: string/numeric/date functions including ENCODE_FOR_URI(), backed by the new encoding module (see below)

Storage & Persistence

  • RdfStore: primary store type — in-memory (RdfStore::new) or disk-backed (RdfStore::open), with automatic N-Quads-based persistence
  • Multi-index access: indexed pattern matching (indexing, storage)
  • Transactions: ACID transaction manager (transaction::{AcidTransaction, TransactionManager})
  • Named graph management: Jena-Dataset-compatible API (named_graph)
  • Jena Assembler: load ja:-vocabulary Turtle configs, Jena fuseki-config.ttl-style (assembler::from_turtle)

Format Support & Serialization

  • Parsers and serializers for Turtle, N-Triples, N-Quads, TriG, RDF/XML, and JSON-LD (parser, serializer, rdfxml, jsonld)
  • Async, chunked, progress-reporting streaming parsers — parser::{AsyncStreamingParser, AsyncRdfSink, MemoryAsyncSink, ParseProgress} and io::async_streaming (behind the async feature)

Performance & Concurrency

  • Lock-free structures: epoch-based concurrent graph access (concurrent)
  • Arena allocation & zero-copy references: optimization::RdfArena, TermRef/TripleRef
  • SIMD-accelerated triple matching: behind the simd feature (simd_triple_matching)
  • SciRS2 integration: scirs2-core provides memory management and parallel iteration (used in place of raw ndarray/direct rayon calls)
  • Benchmark & SLA harness: a Criterion suite under benches/ plus perf_sla::{SloTarget, BenchmarkResult, assert_meets_slo} for regression-gated performance targets, checked against a committed perf_baseline.json

Enterprise & Compliance

  • Audit trail: SOC2/GDPR-oriented structured event logging — audit::{AuditEvent, InMemoryAuditLogger, JsonLineAuditLogger, AuditFilter, GdprService}
  • W3C RDF Dataset Canonicalization (URDNA2015): deterministic blank-node naming for signing and Verifiable Credentials workflows — canon::{canonicalize, Canonicalizer} (re-exported at the crate root)
  • PROV-O provenance tracking: provenance module covering the core W3C PROV-O entities, activities, and agents
  • API stability tracking: a programmatic public-API surface snapshot (api_baseline.json), diffed against the live source by tests/api_stability.rs so unintentional breaking changes fail the test suite
  • Production hardening: production::{HealthCheck, CircuitBreaker, PerformanceMonitor, ResourceQuota}

New in 0.3.2: the encoding module

A pure-std, in-house RFC 3986 percent-encoding implementation — percent_encode, percent_encode_strict, percent_decode — that replaces the external urlencoding crate workspace-wide. It now backs SPARQL's ENCODE_FOR_URI() function and federated-query URL construction (federation::client).

use oxirs_core::encoding::{percent_encode, percent_decode};

let encoded = percent_encode("SELECT * WHERE { ?s ?p ?o }");
assert_eq!(
    encoded,
    "SELECT%20%2A%20WHERE%20%7B%20%3Fs%20%3Fp%20%3Fo%20%7D"
);
assert_eq!(percent_decode(&encoded).unwrap(), "SELECT * WHERE { ?s ?p ?o }");

Installation

Add to your Cargo.toml:

[dependencies]
oxirs-core = "0.3.2"

# Optional: enable async streaming support
oxirs-core = { version = "0.3.2", features = ["async"] }

Feature Flags

Feature Default Description
serde Serialization support for core types
parallel Multi-threaded processing via rayon
rdf-12 RDF 1.2 data model features
rdf-star RDF-star (quoted triples) support
sparql-12 SPARQL 1.2 query features
async Async I/O and streaming parsers
async-tokio Tokio-backed async streaming (implies async)
simd SIMD-accelerated string/term operations (wide)
cuda / opencl GPU backend selectors consumed by platform; live GPU telemetry itself lives in the separate oxirs-gpu-monitor adapter crate (ai::gpu_monitor::GpuMonitor here is a Pure-Rust "no GPU" stub with a matching API)
metal / blas Reserved for future backend crates; not yet wired to any code path in this crate

Quick Start

Creating a Store and Adding Data

use oxirs_core::RdfStore;
use oxirs_core::model::{NamedNode, Triple, Literal};

# fn example() -> Result<(), oxirs_core::OxirsError> {
let mut store = RdfStore::new()?;

let alice = NamedNode::new("http://example.org/alice")?;
let knows = NamedNode::new("http://xmlns.com/foaf/0.1/knows")?;
let bob = NamedNode::new("http://example.org/bob")?;
let name = NamedNode::new("http://xmlns.com/foaf/0.1/name")?;

store.insert_triple(Triple::new(alice.clone(), knows, bob))?;
store.insert_triple(Triple::new(alice, name, Literal::new("Alice")))?;

println!("Store contains {} triples", store.len()?);
# Ok(())
# }

Querying with Pattern Matching

use oxirs_core::RdfStore;
use oxirs_core::model::{NamedNode, Predicate};

# fn query_example() -> Result<(), oxirs_core::OxirsError> {
# let mut store = RdfStore::new()?;
let knows = NamedNode::new("http://xmlns.com/foaf/0.1/knows")?;
let predicate = Predicate::NamedNode(knows);

let triples = store.query_triples(None, Some(&predicate), None)?;
for triple in triples {
    println!("{:?} knows {:?}", triple.subject(), triple.object());
}
# Ok(())
# }

Executing SPARQL Queries

use oxirs_core::RdfStore;

# fn sparql_example() -> Result<(), oxirs_core::OxirsError> {
# let store = RdfStore::new()?;
let query = r#"
    PREFIX foaf: <http://xmlns.com/foaf/0.1/>
    SELECT ?name WHERE {
        ?person foaf:name ?name .
    }
"#;

let results = store.query(query)?;
println!("Query returned {} results", results.len());
# Ok(())
# }

Persistent Storage

use oxirs_core::RdfStore;
use oxirs_core::model::{NamedNode, Triple, Literal};

# fn persistent_example() -> Result<(), oxirs_core::OxirsError> {
// Data is saved under ./my_rdf_store and reloaded automatically on the next open
let mut store = RdfStore::open("./my_rdf_store")?;

let subject = NamedNode::new("http://example.org/resource")?;
let predicate = NamedNode::new("http://purl.org/dc/terms/title")?;
let object = Literal::new("My Resource");

store.insert_triple(Triple::new(subject, predicate, object))?;
# Ok(())
# }

Named Graphs (Quads)

use oxirs_core::RdfStore;
use oxirs_core::model::{NamedNode, Quad, GraphName, Literal};

# fn quads_example() -> Result<(), oxirs_core::OxirsError> {
# let mut store = RdfStore::new()?;
let graph = GraphName::NamedNode(NamedNode::new("http://example.org/graph1")?);
let subject = NamedNode::new("http://example.org/subject")?;
let predicate = NamedNode::new("http://example.org/predicate")?;
let object = Literal::new("value");

store.insert_quad(Quad::new(subject, predicate, object, graph))?;

let graph_node = NamedNode::new("http://example.org/graph1")?;
let quads = store.graph_quads(Some(&graph_node))?;
println!("Graph contains {} quads", quads.len());
# Ok(())
# }

Bulk Loading

use oxirs_core::RdfStore;
use oxirs_core::model::{NamedNode, Triple, Quad, Literal};

# fn bulk_example() -> Result<(), oxirs_core::OxirsError> {
# let mut store = RdfStore::new()?;
let mut quads = Vec::new();
for i in 0..1000 {
    let subject = NamedNode::new(format!("http://example.org/item{i}"))?;
    let predicate = NamedNode::new("http://example.org/value")?;
    let object = Literal::new(i.to_string());
    quads.push(Quad::from_triple(Triple::new(subject, predicate, object)));
}

// Bulk insert is a single call rather than 1000 individual insert_quad() calls
let ids = store.bulk_insert_quads(quads)?;
println!("Inserted {} quads", ids.len());
# Ok(())
# }

More runnable examples live under examples/, including indexed_graph_demo.rs, concurrent_graph_demo.rs, async_streaming.rs, mmap_store_example.rs, sparql_algebra_demo.rs, query_result_cache_demo.rs, and zero_copy_serialization.rs.

Architecture

Core Type System

  • Term: unified enum over all RDF terms
  • NamedNode / BlankNode / Literal / Variable: the four term kinds
  • Triple / Quad: subject-predicate-object(-graph) statements
  • Subject / Predicate / Object: position-typed term enums used in pattern matching
  • TermRef<'a> / TripleRef<'a>: zero-copy borrowed views (optimization module)

Module Organization

Module Purpose
model Core RDF data model types (IRI, literal, blank node, triple, quad)
rdf_store RdfStore and the Store trait — pluggable storage backends
parser / serializer / rdfxml / jsonld RDF parsers and serializers for all supported formats
query / sparql SPARQL algebra, parser, planner, and executor
storage / indexing Storage engine and multi-index structures
concurrent Lock-free, epoch-based concurrent graph access
optimization Arena allocation and zero-copy term references
federation SERVICE-clause distributed query execution
production Health checks, circuit breakers, performance monitoring
transaction ACID transaction manager
named_graph Jena-Dataset-compatible named graph API
assembler Jena Assembler (ja: vocabulary) config loading
audit SOC2/GDPR structured audit trail
canon W3C RDF Dataset Canonicalization (URDNA2015)
provenance W3C PROV-O provenance tracking
encoding RFC 3986 percent-encoding (new in 0.3.2)
oxigraph_compat Drop-in-compatible Store API matching Oxigraph

A handful of modules (consciousness, molecular, quantum) are experimental research surfaces, present in the crate but explicitly outside the API stability guarantees below.

Error Handling

All fallible operations return oxirs_core::Result<T> (an alias for std::result::Result<T, OxirsError>):

use oxirs_core::{OxirsError, Result, NamedNode};

fn parse_iri(iri: &str) -> Result<NamedNode> {
    NamedNode::new(iri).map_err(|e| OxirsError::Parse(e.to_string()))
}

API Stability

  • Stable: core RDF model types (NamedNode, Literal, Triple, Quad), RdfStore operations (insert/query/remove), parser/serializer interfaces
  • Unstable: advanced query-optimization internals (may change without a major version bump)
  • Experimental: consciousness, molecular, and quantum modules

Ecosystem Integration

OxiGraph Compatibility

oxigraph_compat::Store mirrors oxigraph::Store's API — including its interior-mutability semantics, where mutating methods take &self — so migrating existing OxiGraph code is mostly a matter of changing imports:

// Before (with OxiGraph)
use oxigraph::model::{NamedNode, Literal, Triple};

// After (with oxirs-core)
use oxirs_core::model::{NamedNode, Literal, Triple};
use oxirs_core::oxigraph_compat::Store;

OxiRS Platform Components

Every other crate in the workspace builds on oxirs-core:

Development

Running Tests

cd core/oxirs-core
cargo nextest run --all-features
# Current status: 2589 tests passing

Benchmarks

# Criterion suite: indexed_graph, concurrent_graph, parallel_batch, rdf, query_visualization, sla_suite
cargo bench --release

# SLA regression checks (release-only; compares against perf_baseline.json)
cargo test --release -- --ignored sla_suite

Documentation

cargo doc --open --all-features

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass (cargo nextest run --all-features) with zero clippy warnings
  5. Submit a pull request

See CONTRIBUTING.md for full guidelines.

License

Licensed under the Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0).

Status

🚀 Production Release (v0.3.2) — 2,589 tests passing, zero clippy warnings, zero rustdoc errors.

Current Highlights

  • RDF/SPARQL core: RDF 1.2 data model, SPARQL 1.1/1.2 query and update, federation via SERVICE
  • Persistence: RdfStore::open with N-Quads-backed durability
  • Pure-Rust TLS: a #[ctor::ctor] constructor installs OxiTLS's Pure Rust rustls CryptoProvider as the process default for every binary and test process that links this crate, so no ring/aws-lc-sys is required at runtime
  • Compliance tooling: SOC2/GDPR audit trail (audit), URDNA2015 canonicalization (canon), PROV-O provenance (provenance)
  • API stability enforcement: api_baseline.json plus tests/api_stability.rs guard the public surface against accidental breaking changes

Part of the OxiRS semantic web platform.