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>;
}