Skip to main content

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}