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
13pub trait Query: Rdf {
16 fn triples(&self) -> Result<impl Iterator<Item = Self::Triple>, Self::Err>;
17
18 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 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 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}