oxiland/lib.rs
1//! Embedded RDF datasets, SPARQL, persistence, and streaming I/O for Rust.
2//!
3//! Oxiland provides a safe application facade powered by Oxigraph. RDF term
4//! types are re-exported so callers can move data into and out of the broader
5//! Oxigraph ecosystem without adapters. Redland workflow mappings are retained
6//! as an evidence-scoped migration surface without copying manual-memory
7//! ownership rules into Rust (ADR-004).
8//!
9//! # Module layout (1.0 naming freeze intent — ADR-020)
10//!
11//! Stable public modules: [`terms`], [`io`], [`storage`], [`utility`], plus root
12//! re-exports such as [`Model`], [`World`], [`Query`], [`Update`], and [`Error`].
13//! Breaking renames after 0.6 require an ADR and CHANGELOG entry.
14//!
15//! # Quick start
16//!
17//! ```
18//! use oxiland::terms::{self, Literal, Triple};
19//! use oxiland::{Model, Query, QueryResults};
20//!
21//! # fn main() -> oxiland::Result<()> {
22//! let model = Model::new()?;
23//! model.add(Triple::new(
24//! terms::named_node("https://example.com/alice")?,
25//! terms::named_node("https://example.com/name")?,
26//! Literal::new_simple_literal("Alice"),
27//! ))?;
28//!
29//! assert!(matches!(
30//! Query::new("ASK { ?s ?p ?o }").execute(&model)?,
31//! QueryResults::Boolean(true)
32//! ));
33//! # Ok(())
34//! # }
35//! ```
36
37#![forbid(unsafe_code)]
38#![warn(missing_docs)]
39
40mod error;
41pub mod io;
42mod model;
43mod query;
44pub mod storage;
45pub mod utility;
46mod world;
47
48pub use error::{Error, ParseError, Result};
49pub use model::{Model, ModelTransaction, StatementMatches, StatementPattern};
50pub use query::{
51 Query, QueryResults, ResultsFormat, Update, serialize_graph_results_to_writer,
52 serialize_query_results_to_string, serialize_query_results_to_writer,
53};
54pub use storage::{
55 OpenOptions, StorageBackend, StorageCapabilities, compiled_backends, is_known_backend_name,
56};
57pub use world::{FeatureValue, LogFacility, LogLevel, LogRecord, World};
58
59/// RDF term, triple, quad, and graph-name types used by Oxiland.
60///
61/// These are direct re-exports of Oxigraph types (ADR-004). Prefer the helpers
62/// below when you want Oxiland [`Error`] categories instead of Oxigraph errors.
63pub mod terms {
64 pub use oxigraph::model::{
65 BlankNode, GraphName, GraphNameRef, Literal, NamedNode, NamedNodeRef, NamedOrBlankNode,
66 NamedOrBlankNodeRef, Quad, QuadRef, Term, TermRef, Triple, TripleRef, Variable,
67 };
68
69 use crate::{Error, Result};
70
71 /// Creates a [`NamedNode`], mapping IRI failures to [`Error::InvalidRdf`].
72 pub fn named_node(iri: impl AsRef<str>) -> Result<NamedNode> {
73 NamedNode::new(iri.as_ref()).map_err(|error| Error::InvalidRdf(error.to_string()))
74 }
75
76 /// Creates a [`BlankNode`] from an optional identifier.
77 ///
78 /// When `id` is `None`, Oxigraph allocates a fresh blank node. Invalid
79 /// identifiers map to [`Error::InvalidRdf`].
80 pub fn blank_node(id: Option<&str>) -> Result<BlankNode> {
81 match id {
82 Some(id) => BlankNode::new(id).map_err(|error| Error::InvalidRdf(error.to_string())),
83 None => Ok(BlankNode::default()),
84 }
85 }
86}
87
88/// Oxigraph SPARQL primitives for advanced use cases.
89///
90/// Prefer [`Query`], [`Update`], and [`ResultsFormat`] for the documented
91/// Oxiland API. This module is an engine escape hatch, not the compatibility
92/// or stability surface.
93pub mod sparql {
94 pub use oxigraph::sparql::results::{QueryResultsFormat, QueryResultsSerializer};
95 pub use oxigraph::sparql::{
96 CancellationToken, QueryResults, QuerySolution, QuerySolutionIter, QueryTripleIter,
97 SparqlEvaluator,
98 };
99}