Skip to main content

rdf_types/dataset/graph/
fallible.rs

1//! Fallible counterparts of the [`Graph`] traits, for graphs backed by
2//! fallible storage (e.g. a database or a file).
3use crate::{
4	Triple,
5	pattern::LinearTriplePattern,
6	util::{InfallibleIterator, TriplesIntoOwned},
7};
8
9use super::{FiniteGraph, Graph, GraphMut, PatternMatchingGraph};
10
11/// Fallible graph.
12///
13/// A [`Graph`] whose operations may fail with an associated [`Self::Error`]
14/// type.
15///
16/// Every non-fallible [`Graph`] is also a `TryGraph`, with the
17/// [`Infallible`](std::convert::Infallible) error type.
18pub trait TryGraph {
19	/// Resource type.
20	type Resource;
21
22	/// Error type.
23	type Error;
24}
25
26/// Any non-fallible graph can be used as fallible, with the
27/// [`Infallible`](std::convert::Infallible) error type.
28impl<D: Graph> TryGraph for D {
29	type Resource = D::Resource;
30	type Error = std::convert::Infallible;
31}
32
33/// Fallible graph that can be traversed using a provided triple iterator.
34pub trait TryFiniteGraph: TryGraph {
35	/// Fallible triples iterator.
36	type TryTriples<'a>: Iterator<Item = Result<Triple<Self::Resource>, Self::Error>>
37	where
38		Self: 'a;
39
40	/// Returns a fallible iterator over the triples of the graph.
41	fn try_triples(&self) -> Result<Self::TryTriples<'_>, Self::Error>;
42}
43
44/// Any non-fallible finite graph can be used as fallible, with the
45/// [`Infallible`](std::convert::Infallible) error type.
46impl<D: FiniteGraph> TryFiniteGraph for D
47where
48	D::Resource: Clone,
49{
50	type TryTriples<'a>
51		= InfallibleIterator<TriplesIntoOwned<D::Triples<'a>>>
52	where
53		Self: 'a;
54
55	fn try_triples(&self) -> Result<Self::TryTriples<'_>, Self::Error> {
56		Ok(InfallibleIterator(TriplesIntoOwned(self.triples())))
57	}
58}
59
60/// Pattern-matching-capable fallible graph.
61pub trait TryPatternMatchingGraph: TryGraph {
62	/// Fallible pattern-matching iterator.
63	type TryTriplePatternMatching<'a, 'p>: Iterator<
64		Item = Result<Triple<Self::Resource>, Self::Error>,
65	>
66	where
67		Self: 'a,
68		Self::Resource: 'p;
69
70	/// Returns a fallible iterator over all the triples of the graph
71	/// matching the given pattern.
72	fn try_triple_pattern_matching<'p>(
73		&self,
74		pattern: LinearTriplePattern<&'p Self::Resource>,
75	) -> Result<Self::TryTriplePatternMatching<'_, 'p>, Self::Error>;
76
77	/// Checks if the graph contains the given triple.
78	fn try_contains_triple(&self, triple: Triple<&Self::Resource>) -> Result<bool, Self::Error> {
79		Ok(self
80			.try_triple_pattern_matching(triple.into())?
81			.next()
82			.transpose()?
83			.is_some())
84	}
85}
86
87/// Any non-fallible pattern-matching-capable graph can be used as fallible,
88/// with the [`Infallible`](std::convert::Infallible) error type.
89impl<D: PatternMatchingGraph> TryPatternMatchingGraph for D
90where
91	D::Resource: Clone,
92{
93	type TryTriplePatternMatching<'a, 'p>
94		= InfallibleIterator<TriplesIntoOwned<D::TriplePatternMatching<'a, 'p>>>
95	where
96		Self: 'a,
97		Self::Resource: 'p;
98
99	fn try_triple_pattern_matching<'p>(
100		&self,
101		pattern: LinearTriplePattern<&'p Self::Resource>,
102	) -> Result<Self::TryTriplePatternMatching<'_, 'p>, Self::Error> {
103		Ok(InfallibleIterator(TriplesIntoOwned(
104			self.triple_pattern_matching(pattern),
105		)))
106	}
107}
108
109/// Fallible mutable graph.
110pub trait TryGraphMut: TryGraph {
111	/// Tries to insert the given triple in the graph.
112	fn try_insert(&mut self, triple: Triple<Self::Resource>) -> Result<(), Self::Error>;
113}
114
115/// Any non-fallible mutable graph can be used as fallible, with the
116/// [`Infallible`](std::convert::Infallible) error type.
117impl<D: GraphMut> TryGraphMut for D {
118	fn try_insert(&mut self, triple: Triple<Self::Resource>) -> Result<(), Self::Error> {
119		self.insert(triple);
120		Ok(())
121	}
122}