1use std::borrow::Cow;
3
4use crate::{BlankId, CowId, CowLiteral, CowLocalTerm, CowTerm, IdRef, LiteralRef, LocalTermRef, TermRef, TripleTerm};
5
6pub type TripleTermView<'a, R> = (Cow<'a, R>, Cow<'a, R>, Cow<'a, R>);
9
10mod r#impl;
11pub use r#impl::*;
12
13pub mod fallible;
14pub use fallible::FallibleInterpretation;
15
16mod iri;
17pub use iri::*;
18
19mod blank_id;
20pub use blank_id::*;
21
22mod literal;
23pub use literal::*;
24
25mod id;
26pub use id::*;
27
28mod term;
29pub use term::*;
30
31use iri_rs::{Iri, IriBuf};
32
33pub trait Interpretation {
35 type Resource;
36
37 fn iri(&self, iri: Iri<&str>) -> Option<Self::Resource>;
38
39 fn literal<'a>(&self, literal: impl Into<LiteralRef<'a>>) -> Option<Self::Resource>;
40
41 fn term<'a>(&self, term: impl Into<TermRef<'a>>) -> Option<Self::Resource> {
42 match term.into() {
43 TermRef::Iri(iri) => self.iri(iri),
44 TermRef::Literal(l) => self.literal(l),
45 }
46 }
47}
48
49impl<I: Interpretation> Interpretation for &I {
50 type Resource = I::Resource;
51
52 fn iri(&self, iri: Iri<&str>) -> Option<Self::Resource> {
53 I::iri(*self, iri)
54 }
55
56 fn literal<'a>(&self, literal: impl Into<LiteralRef<'a>>) -> Option<Self::Resource> {
57 I::literal(*self, literal)
58 }
59}
60
61impl<I: Interpretation> Interpretation for &mut I {
62 type Resource = I::Resource;
63
64 fn iri(&self, iri: Iri<&str>) -> Option<Self::Resource> {
65 I::iri(*self, iri)
66 }
67
68 fn literal<'a>(&self, literal: impl Into<LiteralRef<'a>>) -> Option<Self::Resource> {
69 I::literal(*self, literal)
70 }
71}
72
73pub trait TraversableInterpretation: Interpretation {
75 type Resources<'a>: Iterator<Item = &'a Self::Resource>
76 where
77 Self: 'a;
78
79 fn resources(&self) -> Self::Resources<'_>;
80}
81
82pub trait GenerativeInterpretation: Interpretation {
84 fn new_resource(&mut self) -> Self::Resource;
86}
87
88pub trait ConstGenerativeInterpretation: Interpretation {
90 fn new_resource(&self) -> Self::Resource;
92}
93
94impl<I: ConstGenerativeInterpretation> GenerativeInterpretation for I {
95 fn new_resource(&mut self) -> Self::Resource {
96 ConstGenerativeInterpretation::new_resource(self)
97 }
98}
99
100pub trait InterpretationMut: Interpretation {
102 fn insert_iri<'a>(&mut self, iri: impl Into<Cow<'a, IriBuf>>) -> Self::Resource;
103
104 fn insert_literal<'a>(&mut self, literal: impl Into<CowLiteral<'a>>) -> Self::Resource;
105
106 fn insert_term<'a>(&mut self, term: impl Into<CowTerm<'a>>) -> Self::Resource {
107 match term.into() {
108 CowTerm::Iri(iri) => self.insert_iri(iri),
109 CowTerm::Literal(literal) => self.insert_literal(literal),
110 }
111 }
112}
113
114pub trait ReverseInterpretation: Interpretation {
116 type Iris<'a>: Iterator<Item = Cow<'a, IriBuf>>
117 where
118 Self: 'a;
119 type Literals<'a>: Iterator<Item = CowLiteral<'a>>
120 where
121 Self: 'a;
122
123 fn iris_of<'a>(&'a self, resource: &'a Self::Resource) -> Self::Iris<'a>;
124
125 fn literals_of<'a>(&'a self, resource: &'a Self::Resource) -> Self::Literals<'a>;
126
127 fn terms_of<'a>(&'a self, resource: &'a Self::Resource) -> TermsOf<'a, Self> {
128 TermsOf {
129 iris: self.iris_of(resource),
130 literals: self.literals_of(resource),
131 }
132 }
133
134 fn triple_term_components(&self, _resource: &Self::Resource) -> Option<(Self::Resource, Self::Resource, Self::Resource)> {
147 None
148 }
149
150 fn triple_term_components_view<'a>(&'a self, resource: &'a Self::Resource) -> Option<TripleTermView<'a, Self::Resource>>
164 where
165 Self::Resource: Clone,
166 {
167 self.triple_term_components(resource).map(|(s, p, o)| (Cow::Owned(s), Cow::Owned(p), Cow::Owned(o)))
168 }
169
170 fn is_blank_id(&self, resource: &Self::Resource) -> bool {
171 self.terms_of(resource).next().is_none() && self.triple_term_components(resource).is_none()
172 }
173}
174
175pub struct TermsOf<'a, I: 'a + ?Sized + ReverseInterpretation> {
176 iris: I::Iris<'a>,
177 literals: I::Literals<'a>,
178}
179
180impl<'a, I: 'a + ?Sized + ReverseInterpretation> Iterator for TermsOf<'a, I> {
181 type Item = CowTerm<'a>;
182
183 fn next(&mut self) -> Option<Self::Item> {
184 self.iris.next().map(CowTerm::Iri).or_else(|| self.literals.next().map(CowTerm::Literal))
185 }
186}
187
188pub trait LocalInterpretation: Interpretation {
189 fn blank_id(&self, blank_id: &BlankId) -> Option<Self::Resource>;
190
191 fn local_term<'a>(&self, term: impl Into<LocalTermRef<'a>>) -> Option<Self::Resource> {
192 match term.into() {
193 LocalTermRef::BlankId(blank_id) => self.blank_id(blank_id),
194 LocalTermRef::Named(term) => self.term(term),
195 LocalTermRef::Triple(t) => self.triple_term(t.clone()),
196 }
197 }
198
199 fn triple_term(&self, _t: TripleTerm) -> Option<Self::Resource> {
203 None
204 }
205
206 fn id<'a>(&self, id: impl Into<IdRef<'a>>) -> Option<Self::Resource> {
207 match id.into() {
208 IdRef::BlankId(blank_id) => self.blank_id(blank_id),
209 IdRef::Iri(iri) => self.iri(iri),
210 }
211 }
212}
213
214pub trait LocalInterpretationMut: InterpretationMut {
215 fn insert_blank_id<'a>(&mut self, blank_id: impl Into<Cow<'a, BlankId>>) -> Self::Resource;
216
217 fn insert_local_term<'a>(&mut self, term: impl Into<CowLocalTerm<'a>>) -> Self::Resource {
218 match term.into() {
219 CowLocalTerm::BlankId(blank_id) => self.insert_blank_id(blank_id),
220 CowLocalTerm::Named(term) => self.insert_term(term),
221 CowLocalTerm::Triple(t) => self.insert_triple_term(t.into_owned()),
222 }
223 }
224
225 fn insert_triple_term(&mut self, _t: TripleTerm) -> Self::Resource {
229 unimplemented!("triple-term insertion not implemented by this LocalInterpretationMut")
230 }
231
232 fn insert_id<'a>(&mut self, term: impl Into<CowId<'a>>) -> Self::Resource {
233 match term.into() {
234 CowId::BlankId(blank_id) => self.insert_blank_id(blank_id),
235 CowId::Iri(iri) => self.insert_iri(iri),
236 }
237 }
238}
239
240pub trait ReverseLocalInterpretation: ReverseInterpretation {
241 type BlankIds<'a>: Iterator<Item = Cow<'a, BlankId>>
242 where
243 Self: 'a;
244
245 fn blank_ids_of<'a>(&'a self, resource: &'a Self::Resource) -> Self::BlankIds<'a>;
246
247 fn local_terms_of<'a>(&'a self, resource: &'a Self::Resource) -> LocalTermsOf<'a, Self> {
248 LocalTermsOf {
249 terms: self.terms_of(resource),
250 blank_ids: self.blank_ids_of(resource),
251 }
252 }
253}
254
255pub struct LocalTermsOf<'a, I: 'a + ?Sized + ReverseLocalInterpretation> {
256 terms: TermsOf<'a, I>,
257 blank_ids: I::BlankIds<'a>,
258}
259
260impl<'a, I: 'a + ?Sized + ReverseLocalInterpretation> Iterator for LocalTermsOf<'a, I> {
261 type Item = CowLocalTerm<'a>;
262
263 fn next(&mut self) -> Option<Self::Item> {
264 self.terms
265 .next()
266 .map(CowLocalTerm::Named)
267 .or_else(|| self.blank_ids.next().map(CowLocalTerm::BlankId))
268 }
269}