oxirs_core/model/mod.rs
1//! Core RDF data model types and implementations
2//!
3//! **Stability**: ✅ **Stable** - These APIs are production-ready and will maintain backward compatibility.
4//!
5//! This module provides the fundamental RDF concepts following the [RDF 1.2 specification](https://www.w3.org/TR/rdf12-concepts/),
6//! with performance optimizations and OxiRS-specific enhancements.
7//!
8//! ## Overview
9//!
10//! The RDF (Resource Description Framework) data model represents information as triples:
11//! **Subject** - **Predicate** - **Object**. This module provides Rust types for all RDF terms
12//! and structures, enabling type-safe manipulation of RDF data.
13//!
14//! ## Core Types
15//!
16//! ### Terms (Basic Building Blocks)
17//!
18//! - **[`NamedNode`]** - An IRI (Internationalized Resource Identifier), the primary way to identify resources
19//! - **[`BlankNode`]** - An anonymous node without a global identifier
20//! - **[`Literal`]** - A data value with optional language tag or datatype
21//! - **[`Variable`]** - A SPARQL query variable (used in query patterns)
22//!
23//! ### Composite Types
24//!
25//! - **[`Triple`]** - A statement with subject, predicate, and object
26//! - **[`Quad`]** - A triple with an optional named graph
27//! - **[`GraphName`]** - Identifies the graph containing a quad (named or default)
28//!
29//! ### Union Types
30//!
31//! - **[`Subject`]** - Can be a NamedNode, BlankNode, or Variable
32//! - **[`Predicate`]** - Can be a NamedNode or Variable
33//! - **[`Object`]** - Can be a NamedNode, BlankNode, Literal, or Variable
34//! - **[`Term`]** - Any RDF term (superset of all above)
35//!
36//! ## Examples
37//!
38//! ### Creating RDF Terms
39//!
40//! ```rust
41//! use oxirs_core::model::*;
42//!
43//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
44//! // Create a Named Node (IRI)
45//! let alice = NamedNode::new("http://example.org/alice")?;
46//!
47//! // Create a Blank Node
48//! let blank = BlankNode::new("b1")?;
49//!
50//! // Create Literals
51//! let plain_literal = Literal::new("Hello, World!");
52//! let typed_literal = Literal::new_typed("42", NamedNode::new("http://www.w3.org/2001/XMLSchema#integer")?);
53//! let lang_literal = Literal::new_lang("Bonjour", "fr")?;
54//!
55//! // Create a Variable (for SPARQL patterns)
56//! let var = Variable::new("name")?;
57//! # Ok(())
58//! # }
59//! ```
60//!
61//! ### Creating Triples
62//!
63//! ```rust
64//! use oxirs_core::model::*;
65//!
66//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
67//! // Create terms
68//! let alice = NamedNode::new("http://example.org/alice")?;
69//! let knows = NamedNode::new("http://xmlns.com/foaf/0.1/knows")?;
70//! let bob = NamedNode::new("http://example.org/bob")?;
71//!
72//! // Create a triple: "Alice knows Bob"
73//! let triple = Triple::new(alice, knows, bob);
74//!
75//! // Access components
76//! println!("Subject: {}", triple.subject());
77//! println!("Predicate: {}", triple.predicate());
78//! println!("Object: {}", triple.object());
79//! # Ok(())
80//! # }
81//! ```
82//!
83//! ### Creating Quads (Named Graphs)
84//!
85//! ```rust
86//! use oxirs_core::model::*;
87//!
88//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
89//! // Create terms
90//! let alice = NamedNode::new("http://example.org/alice")?;
91//! let name = NamedNode::new("http://xmlns.com/foaf/0.1/name")?;
92//! let alice_lit = Literal::new("Alice");
93//!
94//! // Create a named graph
95//! let graph = GraphName::NamedNode(NamedNode::new("http://example.org/graph1")?);
96//!
97//! // Create a quad in the named graph
98//! let quad = Quad::new(alice, name, alice_lit, graph);
99//!
100//! println!("Quad in graph: {}", quad.graph_name());
101//! # Ok(())
102//! # }
103//! ```
104//!
105//! ### Working with Literals
106//!
107//! ```rust
108//! use oxirs_core::model::*;
109//!
110//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
111//! // Plain literal
112//! let plain = Literal::new("Hello");
113//! assert_eq!(plain.value(), "Hello");
114//!
115//! // Language-tagged literal (for internationalization)
116//! let french = Literal::new_lang("Bonjour", "fr")?;
117//! assert_eq!(french.value(), "Bonjour");
118//! assert_eq!(french.language(), Some("fr"));
119//!
120//! // Typed literal (with XSD datatype)
121//! let number = Literal::new_typed(
122//! "42",
123//! NamedNode::new("http://www.w3.org/2001/XMLSchema#integer")?
124//! );
125//! assert_eq!(number.value(), "42");
126//! # Ok(())
127//! # }
128//! ```
129//!
130//! ### Pattern Matching with Variables
131//!
132//! ```rust
133//! use oxirs_core::model::*;
134//!
135//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
136//! // Create a query pattern: "?person foaf:name ?name"
137//! let person_var = Variable::new("person")?;
138//! let name_var = Variable::new("name")?;
139//! let name_pred = NamedNode::new("http://xmlns.com/foaf/0.1/name")?;
140//!
141//! let pattern = Triple::new(person_var, name_pred, name_var);
142//!
143//! // This pattern can be used in SPARQL queries
144//! println!("Pattern: {:?}", pattern);
145//! # Ok(())
146//! # }
147//! ```
148//!
149//! ## Type Conversions
150//!
151//! All term types implement `Into<>` for their union types:
152//!
153//! ```rust
154//! use oxirs_core::model::*;
155//!
156//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
157//! let node = NamedNode::new("http://example.org/resource")?;
158//!
159//! // Automatic conversion to union types
160//! let subject: Subject = node.clone().into();
161//! let predicate: Predicate = node.clone().into();
162//! let object: Object = node.clone().into();
163//! let term: Term = node.into();
164//! # Ok(())
165//! # }
166//! ```
167//!
168//! ## Performance Optimizations
169//!
170//! This module includes several performance optimizations:
171//!
172//! - **String interning** via [`optimized_terms`] for reduced memory usage
173//! - **Zero-copy operations** where possible
174//! - **Efficient hashing** for use in hash-based collections
175//! - **Ordered comparisons** for BTree-based indexes
176//!
177//! ## RDF 1.2 Features
178//!
179//! - **RDF-star support** via [`star`] module for quoted triples
180//! - **Generalized RDF datasets** with named graph support
181//! - **Extended literal datatypes** including language-tagged strings
182//!
183//! ## Related Modules
184//!
185//! - [`crate::parser`] - Parse RDF from various formats
186//! - [`crate::serializer`] - Serialize RDF to various formats
187//! - [`crate::rdf_store`] - Store and query RDF data
188//! - [`crate::query`] - SPARQL query execution
189
190pub mod dataset;
191pub mod graph;
192pub mod iri;
193pub mod literal;
194pub mod namespace_registry; // CURIE prefix ↔ IRI namespace registry (v1.2.0)
195pub mod node;
196pub mod optimized_terms; // Oxigraph-inspired performance optimizations
197pub mod pattern;
198pub mod property_path_evaluator;
199pub mod quad;
200pub mod sparql_binding_set;
201pub mod sparql_optimizer; // SPARQL query plan optimizer with rewrite passes (v1.1.0)
202pub mod star;
203pub mod term;
204pub mod triple;
205pub mod triple_term; // SPARQL binding set algebra: MINUS, EXISTS, JOIN, PROJECT (v1.2.0)
206
207// Re-export core types
208pub use dataset::*;
209pub use graph::*;
210pub use iri::*;
211pub use literal::*;
212pub use node::*;
213pub use optimized_terms::*; // Oxigraph-inspired optimizations
214pub use pattern::*;
215pub use quad::*;
216pub use star::*;
217pub use term::*;
218pub use triple::*;
219
220// Explicit re-exports of union types for external modules
221pub use quad::GraphName;
222pub use term::{Object, Predicate, Subject, Term, Variable};
223
224/// A trait for all RDF terms
225pub trait RdfTerm {
226 /// Returns the string representation of this term
227 fn as_str(&self) -> &str;
228
229 /// Returns true if this is a named node (IRI)
230 fn is_named_node(&self) -> bool {
231 false
232 }
233
234 /// Returns true if this is a blank node
235 fn is_blank_node(&self) -> bool {
236 false
237 }
238
239 /// Returns true if this is a literal
240 fn is_literal(&self) -> bool {
241 false
242 }
243
244 /// Returns true if this is a variable
245 fn is_variable(&self) -> bool {
246 false
247 }
248
249 /// Returns true if this is a quoted triple (RDF-star)
250 fn is_quoted_triple(&self) -> bool {
251 false
252 }
253}
254
255/// A trait for terms that can be used as subjects in RDF triples
256pub trait SubjectTerm: RdfTerm {}
257
258/// A trait for terms that can be used as predicates in RDF triples
259pub trait PredicateTerm: RdfTerm {}
260
261/// A trait for terms that can be used as objects in RDF triples
262pub trait ObjectTerm: RdfTerm {}
263
264/// A trait for terms that can be used in graph names
265pub trait GraphNameTerm: RdfTerm {}