srdf/
srdf.rs

1use std::collections::HashMap;
2use std::collections::HashSet;
3
4use crate::matcher::Any;
5use crate::matcher::Matcher;
6use crate::Rdf;
7use crate::Triple;
8
9pub type IncomingArcs<R> = HashMap<<R as Rdf>::IRI, HashSet<<R as Rdf>::Subject>>;
10pub type OutgoingArcs<R> = HashMap<<R as Rdf>::IRI, HashSet<<R as Rdf>::Term>>;
11pub type OutgoingArcsFromList<R> = (OutgoingArcs<R>, Vec<<R as Rdf>::IRI>);
12
13/// This trait contains functions to handle basic navigation in RDF graphs,
14/// with methods that can get triples and the neighbourhood of RDF nodes
15pub trait Query: Rdf {
16    fn triples(&self) -> Result<impl Iterator<Item = Self::Triple>, Self::Err>;
17
18    /// Note to implementors: this function needs to retrieve all the triples of
19    /// the graph. Therefore, for use-cases where the graph is large, this
20    /// function should be implemented in a way that it does not retrieve all
21    /// triples at once. As an example, for implementations of SPARQL, this
22    /// function should be implemented to retrieve just the triples that match
23    /// the given subject, predicate and object.
24    fn triples_matching<S, P, O>(
25        &self,
26        subject: S,
27        predicate: P,
28        object: O,
29    ) -> Result<impl Iterator<Item = Self::Triple>, Self::Err>
30    where
31        S: Matcher<Self::Subject>,
32        P: Matcher<Self::IRI>,
33        O: Matcher<Self::Term>,
34    {
35        let triples = self.triples()?.filter_map(move |triple| {
36            match subject == triple.subj() && predicate == triple.pred() && object == triple.obj() {
37                true => Some(triple),
38                false => None,
39            }
40        });
41        Ok(triples)
42    }
43
44    fn triples_with_subject<S: Matcher<Self::Subject>>(
45        &self,
46        subject: S,
47    ) -> Result<impl Iterator<Item = Self::Triple>, Self::Err> {
48        self.triples_matching(subject, Any, Any)
49    }
50
51    fn triples_with_predicate<P: Matcher<Self::IRI>>(
52        &self,
53        predicate: P,
54    ) -> Result<impl Iterator<Item = Self::Triple>, Self::Err> {
55        self.triples_matching(Any, predicate, Any)
56    }
57
58    fn triples_with_object<O: Matcher<Self::Term>>(
59        &self,
60        object: O,
61    ) -> Result<impl Iterator<Item = Self::Triple>, Self::Err> {
62        self.triples_matching(Any, Any, object)
63    }
64
65    fn incoming_arcs(&self, object: Self::Term) -> Result<IncomingArcs<Self>, Self::Err> {
66        let mut results = IncomingArcs::<Self>::new();
67        for triple in self.triples_with_object(object.clone())? {
68            let (s, p, _) = triple.into_components();
69            results.entry(p).or_default().insert(s);
70        }
71        Ok(results)
72    }
73
74    /// get all outgoing arcs from a subject
75    fn outgoing_arcs(&self, subject: Self::Subject) -> Result<OutgoingArcs<Self>, Self::Err> {
76        let mut results = OutgoingArcs::<Self>::new();
77        for triple in self.triples_with_subject(subject.clone())? {
78            let (_, p, o) = triple.into_components();
79            results.entry(p).or_default().insert(o);
80        }
81        Ok(results)
82    }
83
84    /// get outgoing arcs from a `node` taking into account only a controlled list of `preds`
85    /// It returns a HashMap with the outgoing arcs and their values and a list of the predicates that have values and are not in the controlled list.
86    fn outgoing_arcs_from_list(
87        &self,
88        subject: &Self::Subject,
89        preds: &[Self::IRI],
90    ) -> Result<OutgoingArcsFromList<Self>, Self::Err> {
91        let mut results = OutgoingArcs::<Self>::new();
92        let mut remainder = Vec::new();
93
94        for triple in self.triples_with_subject(subject.clone())? {
95            let (_, p, o) = triple.into_components();
96            if preds.contains(&p) {
97                results.entry(p).or_default().insert(o);
98            } else {
99                remainder.push(p)
100            }
101        }
102
103        Ok((results, remainder))
104    }
105}