rudof_rdf
The rudof_rdf crate is a core component of the Rudof project, providing foundational data structures, utilities, and algorithms for working with RDF (Resource Description Framework) data in Rust. It supports parsing, querying, manipulating, and visualizing RDF graphs, and serves as the backbone for higher-level crates in the Rudof ecosystem.
Architecture and Package Structure
The crate is organized into several key modules:
- rdf_core: Core logic for RDF handling, including:
term: RDF terms (IRIs, blank nodes, literals, triples)parser: Parsers for RDF nodes and documentsquery: SPARQL query support and result handlingvocab: Common RDF, RDFS, XSD, and SHACL vocabulary constantsutils: Utilities such as regex helpersvisualizer: Tools for visualizing RDF graphs (UML, styles, etc.)matcher,focus_rdf,neighs_rdf, etc.: Advanced graph navigation and matching
- rdf_impl: Implementations of RDF storage and access:
in_memory_graph: In-memory RDF graph implementationsparql_endpoint: SPARQL endpoint integrationoxrdf_impl: Integration with theoxrdfcrate
Dependents and dependencies
This create depends mostly on:
- Internal Rudof crates:
- External:
oxigraphoxrdfoxjsonldoxirioxilangtagoxrdfiooxrdfxmloxsdatatypesoxttlreqwesttokio
This crate is a foundational dependency for many other Rudof crates, including:
rudof_librudof_clishacl_ast,shacl_ir,shacl_rdf,shacl_validationshex_ast,shex_validationshex_testsuite,shapes_comparator,shapes_converter,sparql_service, and others.
Usage
The following examples illustrate just one of the many features rdf provides — fluent parser composition:
Composing Parsers with Fluent API
use rudof_rdf::rdf_core::{ FocusRDF, parser::{ RDFParse, rdf_node_parser::{ RDFNodeParse, // Core trait ParserExt, // Extension trait (fluent API) constructors::{ ObjectParser, // captures the current focus node as an Object SingleStringPropertyParser, // reads a single string-valued property ListParser, // traverses an RDF list (rdf:first/rdf:rest) }, }, }, term::{Object, literal::Lang}, }; use rudof_rdf::rdf_impl::{InMemoryGraph, ReaderMode}; use rudof_rdf::rdf_core::RDFFormat; use iri_s::IriS; // The domain type we want to build from the RDF graph. #[derive(Debug, Clone)] struct PersonShape { id: Object, name: String, known_langs: Vec, } // --- Individual field parsers (reusable building blocks) --- /// Reads the single string value of sh:name on the current focus node. fn parse_name() -> impl RDFNodeParse { let sh_name = IriS::new_unchecked("http://www.w3.org/ns/shacl#name"); SingleStringPropertyParser::new(sh_name) } /// Reads sh:languageIn ( "en" "fr" ) and returns a Vec. fn parse_language_in() -> impl RDFNodeParse> { let sh_language_in = IriS::new_unchecked("http://www.w3.org/ns/shacl#languageIn"); ListParser::new() .flat_map(|terms: Vec| { let langs: Vec = terms.iter().flat_map(RDF::term_as_lang).collect(); Ok(langs) }) .map_property(sh_language_in) .map(|mut vecs| vecs.pop().unwrap_or_default()) } // --- Composite parser built with the fluent API --- /// Combines all field parsers into a single `PersonShape`. fn person_shape_parser() -> impl RDFNodeParse { ObjectParser::new() .then(move |id: Object| { parse_name() .and(parse_language_in()) .flat_map(move |(name, langs)| { Ok(PersonShape { id: id.clone(), name, known_langs: langs, }) }) }) } fn main() { let turtle = r#" @prefix ex: <http://example.org/> . @prefix sh: <http://www.w3.org/ns/shacl#> . ex:Alice sh:name "Alice" ; sh:languageIn ( "en" "fr" ) . "#; // 1. Parse a Turtle string into an in-memory RDF graph. let graph = InMemoryGraph::from_str( turtle, &RDFFormat::Turtle, None, &ReaderMode::default(), ) .expect("Failed to parse Turtle"); // 2. Wrap the graph in RDFParse, which tracks the mutable focus node. let mut rdf_parse = RDFParse::new(graph); // 3. Point the focus at the node we want to parse. let alice: Object = IriS::new_unchecked("http://example.org/Alice").into(); rdf_parse.rdf_mut().set_focus(&alice.clone().into()); // 4. Run the composite parser. let person = person_shape_parser() .parse_focused(rdf_parse.rdf_mut()) .expect("Parsing failed"); println!("Parsed: {:?}", person); // Parsed: PersonShape { id: Iri { .. "http://example.org/Alice" }, // name: "Alice", // known_langs: [Lang { lang: "en" }, Lang { lang: "fr" }] } }
Documentation
The crate documentation can be found here.