1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
//! The [Resource Description Framework (RDF)](https://en.wikipedia.org/wiki/Resource_Description_Framework) //! is a powerful method for modeling data and knowledge //! defined by the [World Wide Web Consorsium (W3C)](https://www.w3.org/). //! A RDF dataset consists in a collection of graphs connecting nodes, values //! and predicates. This crate provides traits and implementations of //! [Generalized RDF (gRDF)](https://www.w3.org/TR/2014/REC-rdf11-concepts-20140225/#section-generalized-rdf) //! where nodes, values and predicates have the same representation. //! //! Note that this crates requires the nightly compiler. //! It needs Generic Associated Typed (GAT) to work properly, //! which are [still being implemented](https://github.com/rust-lang/rust/issues/44265). //! //! ## Basic usage //! //! ### Exploring a dataset //! //! Each `Dataset` implementation provides many iterators to explore the data. //! One simple way is to iterate through the quad of the dataset: //! //! ```rust //! # use grdf::{Term, Dataset, Quad, HashDataset}; //! # let dataset: HashDataset<Term> = HashDataset::new(); //! for Quad(graph, subject, predicate, object) in dataset.quads() { //! // do something //! } //! ``` //! //! Another way is to access each graph individually using `Dataset::graph`. //! For a given graph, it is then possible to iterate through the triples of the //! graph: //! //! ```rust //! # use grdf::{Term, Dataset, Graph, Triple, HashDataset}; //! # let dataset: HashDataset<Term> = HashDataset::new(); //! # let id = None; //! let graph = dataset.graph(id).unwrap(); //! //! for Triple(subject, predicate, object) in graph.triples() { //! // do something //! } //! ``` //! //! It is also possible to explore the graph logically, subject by subject, //! predicate by predicate, object by object: //! //! ```rust //! # use grdf::{Term, Graph, HashGraph}; //! # let graph: HashGraph<Term> = HashGraph::new(); //! // for each subject of the graph... //! for (subject, predicates) in graph.subjects() { //! // for each predicate it is subject... //! for (predicate, objects) in predicates { //! // for each triple (subject, predicate, object)... //! for object in objects { //! // do something //! } //! } //! } //! ``` //! //! ### Inserting new data //! //! Insertion can be done on `MutableDataset` implementations using //! `MutableDataset::insert`: //! //! ```rust //! # use grdf::{Term, MutableDataset, Quad, HashDataset}; //! # let graph = None; //! # let subject = Term::Blank(0); //! # let predicate = Term::Blank(1); //! # let object = Term::Blank(2); //! let mut dataset: HashDataset<Term> = HashDataset::new(); //! dataset.insert(Quad(graph, subject, predicate, object)); //! ``` //! //! Again it is possible to access each graph of the dataset mutably: //! //! ```rust //! # use grdf::{Term, MutableDataset, MutableGraph, Triple, HashDataset}; //! # let id = None; //! # let subject = Term::Blank(0); //! # let predicate = Term::Blank(1); //! # let object = Term::Blank(2); //! # let mut dataset: HashDataset<Term> = HashDataset::new(); //! let mut graph = dataset.graph_mut(id).unwrap(); //! graph.insert(Triple(subject, predicate, object)); //! ``` //! //! ### Custom node type //! //! The type used to represent RDF nodes (subjects, predicate and objects) is a //! parameter of the dataset. Anything can be used although this crate provide a //! default `Term` type that represents generic RDF nodes (blank nodes, //! IRI-named nodes and literal values). #![feature(generic_associated_types)] use std::fmt; pub mod hash_dataset; mod term; pub use hash_dataset::{HashDataset, HashGraph}; pub use term::*; /// gRDF triple. pub struct Triple<T>(pub T, pub T, pub T); impl<T> Triple<T> { pub fn subject(&self) -> &T { &self.0 } pub fn predicate(&self) -> &T { &self.1 } pub fn object(&self) -> &T { &self.2 } pub fn into_parts(self) -> (T, T, T) { (self.0, self.1, self.2) } } impl<T: fmt::Display> fmt::Display for Triple<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{} {} {}", self.0, self.1, self.2) } } /// gRDF graph. /// /// A graph is a collection of RDF triples. /// It also defines a set of iterator to easily explore the graph. pub trait Graph<T = crate::Term> { /// Triple iterators. type Triples<'a>: Iterator<Item = Triple<&'a T>> where T: 'a; /// Graph subjects iterator. /// /// Each subject is given with its associated predicates (and objects). type Subjects<'a>: Iterator<Item = (&'a T, Self::Predicates<'a>)> where T: 'a; /// Subject predicates iterator. /// /// Iterate through all the predicates associated to a given subject. /// Each predicate is also given with the associated objects. type Predicates<'a>: Iterator<Item = (&'a T, Self::Objects<'a>)> where T: 'a; /// Objects iterator. /// /// Iterate through a set of objects. type Objects<'a>: Iterator<Item = &'a T> where T: 'a; // Iterate through all the triples defined in the graph. fn triples<'a>(&'a self) -> Self::Triples<'a> where T: 'a; /// Iterate through all the subjects of the graph. fn subjects<'a>(&'a self) -> Self::Subjects<'a> where T: 'a; /// Iterate through all the predicates associated to the given subject. fn predicates<'a>(&'a self, subject: &T) -> Self::Predicates<'a> where T: 'a; /// Iterate through all the objects associated to the given subject and /// predicate. fn objects<'a>( &'a self, subject: &T, predicate: &T, ) -> Self::Objects<'a> where T: 'a; /// Checks if the given triple is defined in the graph. fn contains(&self, triple: Triple<&T>) -> bool; } /// Sized gRDF graph that can be converted into iterators. /// /// Defines a set of iterators the graph can be consumed into. pub trait SizedGraph<T = crate::Term>: Graph<T> + Sized { /// Consuming triples iterator. type IntoTriples: Iterator<Item = Triple<T>>; /// Consuming subjects iterator. type IntoSubjects: Iterator<Item = (T, Self::IntoPredicates)>; /// Consuming predicates iterator. type IntoPredicates: Iterator<Item = (T, Self::IntoObjects)>; /// Consuming objects iterator. type IntoObjects: Iterator<Item = T>; /// Consumes the graph and returns an iterator over its triples. fn into_triples(self) -> Self::IntoTriples; /// Consumes the graph and returns an iterator over its subjects. fn into_subjects(self) -> Self::IntoSubjects; /// Consumes the graph and returns an iterator over the predicates of the /// given subject. fn into_predicates(self, subject: &T) -> Self::IntoPredicates; /// Consumes the graph and returns an iterator over the objects of the given /// subject and predicate. fn into_objects(self, subject: &T, predicate: &T) -> Self::IntoObjects; } /// Mutable gRDF graph. pub trait MutableGraph<T = crate::Term>: Graph<T> { /// Insert the given triple into the graph. fn insert(&mut self, triple: Triple<T>); /// Absorb the given other graph. /// /// Adds all the triples of `other` in the graph. fn absorb<G: SizedGraph<T>>(&mut self, other: G); } /// gRDF quad. pub struct Quad<T>(pub Option<T>, pub T, pub T, pub T); impl<T> Quad<T> { pub fn graph(&self) -> Option<&T> { self.0.as_ref() } pub fn subject(&self) -> &T { &self.1 } pub fn predicate(&self) -> &T { &self.2 } pub fn object(&self) -> &T { &self.3 } pub fn into_parts(self) -> (Option<T>, T, T, T) { (self.0, self.1, self.2, self.3) } } impl<T: fmt::Display> fmt::Display for Quad<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self.graph() { Some(graph) => write!(f, "{} {} {} {}", self.1, self.2, self.3, graph), None => write!(f, "{} {} {}", self.1, self.2, self.3) } } } /// gRDF dataset. /// /// A dataset is a collection of graphs. /// It is made of a default graph and a collection of named graphs. /// /// A dataset can also be seen as a collection of [`Quad`]s. pub trait Dataset<T = crate::Term> { /// Type of graphs in the dataset. type Graph: Graph<T>; /// Graph iterator. /// /// Each graph is associated to its name (if any). type Graphs<'a>: Iterator<Item = (Option<&'a T>, &'a Self::Graph)> where T: 'a, Self::Graph: 'a; /// Quads iterator. type Quads<'a>: Iterator<Item = Quad<&'a T>> where T: 'a; /// Get the graph with the given name. /// Input `None` to get the default graph. /// /// Note to implementors: the default graph should always exists. fn graph(&self, id: Option<&T>) -> Option<&Self::Graph>; /// Get the default graph of the dataset. /// /// This is the same as `graph(None)`. /// /// Note to implementors: the default graph should always exists. fn default_graph(&self) -> &Self::Graph { self.graph(None).unwrap() } /// Returns an iterator over the graphs of the dataset. fn graphs<'a>(&'a self) -> Self::Graphs<'a>; /// Returns an iterator over the quads of the dataset. fn quads<'a>(&'a self) -> Self::Quads<'a>; /// Iterate through all the subjects of the given graph. fn subjects<'a>( &'a self, id: Option<&T>, ) -> Option<<Self::Graph as Graph<T>>::Subjects<'a>> where Self::Graph: 'a, T: 'a { match self.graph(id) { Some(graph) => Some(graph.subjects()), None => None, } } /// Iterate through all the predicates of the given subject of the given /// graph. fn predicates<'a>( &'a self, id: Option<&T>, subject: &T, ) -> Option<<Self::Graph as Graph<T>>::Predicates<'a>> where Self::Graph: 'a, T: 'a { match self.graph(id) { Some(graph) => Some(graph.predicates(subject)), None => None, } } /// Iterate through all the objects of the given subect and predicate of the /// given graph. fn objects<'a>( &'a self, id: Option<&T>, subject: &T, predicate: &T, ) -> Option<<Self::Graph as Graph<T>>::Objects<'a>> where Self::Graph: 'a, T: 'a { match self.graph(id) { Some(graph) => Some(graph.objects(subject, predicate)), None => None, } } } /// Sized gRDF dataset that can be converted into iterators. pub trait SizedDataset<T = crate::Term>: Dataset<T> + Sized where Self::Graph: SizedGraph<T>, { /// Consuming graphs iterator. type IntoGraphs: Iterator<Item = (Option<T>, Self::Graph)>; /// Consuming quads iterator. type IntoQuads: Iterator<Item = Quad<T>>; /// Consumes the dataset and returns the given graph. fn into_graph(self, id: Option<&T>) -> Option<Self::Graph>; /// Consumes the dataset and returns the default graph. fn into_default_graph(self) -> Self::Graph { self.into_graph(None).unwrap() } /// Consumes the dataset and returns an iterator over its graphs. fn into_graphs(self) -> Self::IntoGraphs; /// Consumes the dataset and returns an iterator over its quads. fn into_quads(self) -> Self::IntoQuads; /// Consumes the dataset and returns an iterator over the subjects of the /// given graph. fn subjects(self, id: Option<&T>) -> Option<<Self::Graph as SizedGraph<T>>::IntoSubjects> { match self.into_graph(id) { Some(graph) => Some(graph.into_subjects()), None => None, } } /// Consumes the dataset and returns an iterator over the predicates of the /// given subject of the given graph. fn predicates( self, id: Option<&T>, subject: &T, ) -> Option<<Self::Graph as SizedGraph<T>>::IntoPredicates> { match self.into_graph(id) { Some(graph) => Some(graph.into_predicates(subject)), None => None, } } /// Consumes the dataset and returns an iterator over the objects of the /// given subject and predicate of the given graph. fn objects( self, id: Option<&T>, subject: &T, predicate: &T, ) -> Option<<Self::Graph as SizedGraph<T>>::IntoObjects> { match self.into_graph(id) { Some(graph) => Some(graph.into_objects(subject, predicate)), None => None, } } } /// Mutable dataset. pub trait MutableDataset<T = crate::Term>: Dataset<T> { /// Iterator over mutable graphs. type GraphsMut<'a>: Iterator<Item = (Option<&'a T>, &'a mut Self::Graph)> where T: 'a, Self::Graph: 'a; /// Get the given graph mutabily. /// /// Use the input `None` to get the default graph. /// /// Note to implementors: the default graph should always exists. fn graph_mut(&mut self, id: Option<&T>) -> Option<&mut Self::Graph>; /// Get the default graph mutabily. /// /// Note to implementors: the default graph should always exists. fn default_graph_mut(&mut self) -> &mut Self::Graph { self.graph_mut(None).unwrap() } /// Returns an iterator over the (mutable) graphs of the dataset. fn graphs_mut<'a>(&'a mut self) -> Self::GraphsMut<'a>; /// Insert a graph in the dataset with the given name. /// /// If a graph with the given name already exists, /// it is replaced and the previous graph definition is returned. fn insert_graph(&mut self, id: T, graph: Self::Graph) -> Option<Self::Graph>; /// Insert a quad in the dataset. fn insert(&mut self, quad: Quad<T>); /// Absorb the given other dataset. /// /// Adds all the quads of `other` in the dataset. fn absorb<D: SizedDataset<T>>(&mut self, other: D) where D::Graph: SizedGraph<T>; }