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)
168 .map(|(s, p, o)| (Cow::Owned(s), Cow::Owned(p), Cow::Owned(o)))
169 }
170
171 fn is_blank_id(&self, resource: &Self::Resource) -> bool {
172 self.terms_of(resource).next().is_none() && self.triple_term_components(resource).is_none()
173 }
174}
175
176pub struct TermsOf<'a, I: 'a + ?Sized + ReverseInterpretation> {
177 iris: I::Iris<'a>,
178 literals: I::Literals<'a>,
179}
180
181impl<'a, I: 'a + ?Sized + ReverseInterpretation> Iterator for TermsOf<'a, I> {
182 type Item = CowTerm<'a>;
183
184 fn next(&mut self) -> Option<Self::Item> {
185 self.iris.next().map(CowTerm::Iri).or_else(|| self.literals.next().map(CowTerm::Literal))
186 }
187}
188
189pub trait LocalInterpretation: Interpretation {
190 fn blank_id(&self, blank_id: &BlankId) -> Option<Self::Resource>;
191
192 fn local_term<'a>(&self, term: impl Into<LocalTermRef<'a>>) -> Option<Self::Resource> {
193 match term.into() {
194 LocalTermRef::BlankId(blank_id) => self.blank_id(blank_id),
195 LocalTermRef::Named(term) => self.term(term),
196 LocalTermRef::Triple(t) => self.triple_term(t.clone()),
197 }
198 }
199
200 fn triple_term(&self, _t: TripleTerm) -> Option<Self::Resource> {
204 None
205 }
206
207 fn id<'a>(&self, id: impl Into<IdRef<'a>>) -> Option<Self::Resource> {
208 match id.into() {
209 IdRef::BlankId(blank_id) => self.blank_id(blank_id),
210 IdRef::Iri(iri) => self.iri(iri),
211 }
212 }
213}
214
215pub trait LocalInterpretationMut: InterpretationMut {
216 fn insert_blank_id<'a>(&mut self, blank_id: impl Into<Cow<'a, BlankId>>) -> Self::Resource;
217
218 fn insert_local_term<'a>(&mut self, term: impl Into<CowLocalTerm<'a>>) -> Self::Resource {
219 match term.into() {
220 CowLocalTerm::BlankId(blank_id) => self.insert_blank_id(blank_id),
221 CowLocalTerm::Named(term) => self.insert_term(term),
222 CowLocalTerm::Triple(t) => self.insert_triple_term(t.into_owned()),
223 }
224 }
225
226 fn insert_triple_term(&mut self, _t: TripleTerm) -> Self::Resource {
230 unimplemented!("triple-term insertion not implemented by this LocalInterpretationMut")
231 }
232
233 fn insert_id<'a>(&mut self, term: impl Into<CowId<'a>>) -> Self::Resource {
234 match term.into() {
235 CowId::BlankId(blank_id) => self.insert_blank_id(blank_id),
236 CowId::Iri(iri) => self.insert_iri(iri),
237 }
238 }
239}
240
241pub trait ReverseLocalInterpretation: ReverseInterpretation {
242 type BlankIds<'a>: Iterator<Item = Cow<'a, BlankId>>
243 where
244 Self: 'a;
245
246 fn blank_ids_of<'a>(&'a self, resource: &'a Self::Resource) -> Self::BlankIds<'a>;
247
248 fn local_terms_of<'a>(&'a self, resource: &'a Self::Resource) -> LocalTermsOf<'a, Self> {
249 LocalTermsOf {
250 terms: self.terms_of(resource),
251 blank_ids: self.blank_ids_of(resource),
252 }
253 }
254}
255
256pub struct LocalTermsOf<'a, I: 'a + ?Sized + ReverseLocalInterpretation> {
257 terms: TermsOf<'a, I>,
258 blank_ids: I::BlankIds<'a>,
259}
260
261impl<'a, I: 'a + ?Sized + ReverseLocalInterpretation> Iterator for LocalTermsOf<'a, I> {
262 type Item = CowLocalTerm<'a>;
263
264 fn next(&mut self) -> Option<Self::Item> {
265 self.terms
266 .next()
267 .map(CowLocalTerm::Named)
268 .or_else(|| self.blank_ids.next().map(CowLocalTerm::BlankId))
269 }
270}