1use educe::Educe;
2use iref::{Iri, IriBuf};
3use rdf_types::{
4 interpretation::ReverseTermInterpretation,
5 vocabulary::{BlankIdVocabularyMut, IriVocabularyMut},
6 BlankId, BlankIdBuf, Id, Interpretation, Term, Vocabulary,
7};
8use std::fmt;
9
10use crate::{AsRdfLiteral, CowRdfTerm};
11
12#[derive(Educe)]
14#[educe(Debug(bound = "I::Resource: fmt::Debug, V::Iri: fmt::Debug, V::BlankId: fmt::Debug"))]
15pub enum ResourceInterpretation<'a, I: Interpretation, V: Vocabulary> {
16 Interpreted(&'a I::Resource),
18
19 Uninterpreted(Option<CowRdfTerm<'a, V>>),
24}
25
26impl<'a, I: Interpretation, V: Vocabulary> ResourceInterpretation<'a, I, V> {
27 pub fn as_interpreted(&self) -> Option<&'a I::Resource> {
28 match self {
29 Self::Interpreted(i) => Some(i),
30 _ => None,
31 }
32 }
33
34 pub fn as_uninterpreted(&self) -> Option<&CowRdfTerm<'a, V>> {
35 match self {
36 Self::Uninterpreted(t) => t.as_ref(),
37 _ => None,
38 }
39 }
40
41 pub fn into_lexical_representation(
42 self,
43 vocabulary: &'a V,
44 interpretation: &'a I,
45 ) -> Option<CowRdfTerm<'a, V>>
46 where
47 I: ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
48 {
49 match self {
50 Self::Interpreted(r) => {
51 if let Some(i) = interpretation.iris_of(r).next() {
52 return Some(CowRdfTerm::Borrowed(Term::Id(Id::Iri(i))));
53 }
54
55 if let Some(l) = interpretation.literals_of(r).next() {
56 let l = vocabulary.literal(l).unwrap();
57 let term = match l.value.as_rdf_literal(vocabulary, l.type_) {
58 crate::CowRdfLiteral::Borrowed(l) => CowRdfTerm::Borrowed(Term::Literal(l)),
59 crate::CowRdfLiteral::Owned(l) => CowRdfTerm::Owned(Term::Literal(l)),
60 };
61
62 return Some(term);
63 }
64
65 if let Some(b) = interpretation.blank_ids_of(r).next() {
66 return Some(CowRdfTerm::Borrowed(Term::Id(Id::Blank(b))));
67 }
68
69 None
70 }
71 Self::Uninterpreted(t) => t,
72 }
73 }
74}
75
76pub trait LinkedDataResourceRef<'a, I: Interpretation = (), V: Vocabulary = ()> {
78 fn interpretation_ref(
79 &self,
80 vocabulary: &mut V,
81 interpretation: &mut I,
82 ) -> ResourceInterpretation<'a, I, V>;
83}
84
85pub trait LinkedDataResource<I: Interpretation = (), V: Vocabulary = ()> {
87 fn interpretation(
88 &self,
89 vocabulary: &mut V,
90 interpretation: &mut I,
91 ) -> ResourceInterpretation<I, V>;
92
93 fn lexical_representation<'a>(
94 &'a self,
95 vocabulary: &'a mut V,
96 interpretation: &'a mut I,
97 ) -> Option<CowRdfTerm<'a, V>>
98 where
99 I: ReverseTermInterpretation<Iri = V::Iri, BlankId = V::BlankId, Literal = V::Literal>,
100 {
101 self.interpretation(vocabulary, interpretation)
102 .into_lexical_representation(vocabulary, interpretation)
103 }
104
105 fn reference_interpretation(
106 &self,
107 vocabulary: &mut V,
108 interpretation: &mut I,
109 ) -> ResourceInterpretation<I, V> {
110 self.interpretation(vocabulary, interpretation)
111 }
112}
113
114impl<I: Interpretation, V: Vocabulary, T: ?Sized + LinkedDataResource<I, V>>
115 LinkedDataResource<I, V> for &T
116{
117 fn interpretation(
118 &self,
119 vocabulary: &mut V,
120 interpretation: &mut I,
121 ) -> ResourceInterpretation<I, V> {
122 T::interpretation(self, vocabulary, interpretation)
123 }
124}
125
126impl<I: Interpretation, V: Vocabulary, T: ?Sized + LinkedDataResource<I, V>>
127 LinkedDataResource<I, V> for Box<T>
128{
129 fn interpretation(
130 &self,
131 vocabulary: &mut V,
132 interpretation: &mut I,
133 ) -> ResourceInterpretation<I, V> {
134 T::interpretation(self, vocabulary, interpretation)
135 }
136}
137
138impl<I: Interpretation, V: Vocabulary> LinkedDataResource<I, V> for () {
139 fn interpretation(
140 &self,
141 _vocabulary: &mut V,
142 _interpretation: &mut I,
143 ) -> ResourceInterpretation<I, V> {
144 ResourceInterpretation::Uninterpreted(None)
145 }
146}
147
148pub struct Anonymous;
153
154impl<I: Interpretation, V: Vocabulary> LinkedDataResource<I, V> for Anonymous {
155 fn interpretation(
156 &self,
157 _vocabulary: &mut V,
158 _interpretation: &mut I,
159 ) -> ResourceInterpretation<I, V> {
160 ResourceInterpretation::Uninterpreted(None)
161 }
162}
163
164impl<V: Vocabulary + IriVocabularyMut, I: Interpretation> LinkedDataResource<I, V> for Iri {
165 fn interpretation(
166 &self,
167 vocabulary: &mut V,
168 _interpretation: &mut I,
169 ) -> ResourceInterpretation<I, V> {
170 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Owned(Term::Id(Id::Iri(
171 vocabulary.insert(self),
172 )))))
173 }
174}
175
176impl<V: Vocabulary + IriVocabularyMut, I: Interpretation> LinkedDataResource<I, V> for IriBuf {
177 fn interpretation(
178 &self,
179 vocabulary: &mut V,
180 _interpretation: &mut I,
181 ) -> ResourceInterpretation<I, V> {
182 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Owned(Term::Id(Id::Iri(
183 vocabulary.insert(self),
184 )))))
185 }
186}
187
188impl<V: Vocabulary + BlankIdVocabularyMut, I: Interpretation> LinkedDataResource<I, V> for BlankId {
189 fn interpretation(
190 &self,
191 vocabulary: &mut V,
192 _interpretation: &mut I,
193 ) -> ResourceInterpretation<I, V> {
194 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Owned(Term::Id(Id::Blank(
195 vocabulary.insert_blank_id(self),
196 )))))
197 }
198}
199
200impl<V: Vocabulary + BlankIdVocabularyMut, I: Interpretation> LinkedDataResource<I, V>
201 for BlankIdBuf
202{
203 fn interpretation(
204 &self,
205 vocabulary: &mut V,
206 _interpretation: &mut I,
207 ) -> ResourceInterpretation<I, V> {
208 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Owned(Term::Id(Id::Blank(
209 vocabulary.insert_blank_id(self),
210 )))))
211 }
212}
213
214impl<
215 V: Vocabulary,
216 I: Interpretation,
217 T: LinkedDataResource<I, V>,
218 B: LinkedDataResource<I, V>,
219 > LinkedDataResource<I, V> for Id<T, B>
220{
221 fn interpretation(
222 &self,
223 vocabulary: &mut V,
224 interpretation: &mut I,
225 ) -> ResourceInterpretation<I, V> {
226 match self {
227 Self::Iri(i) => i.reference_interpretation(vocabulary, interpretation),
228 Self::Blank(b) => b.reference_interpretation(vocabulary, interpretation),
229 }
230 }
231}
232
233impl<
234 V: Vocabulary,
235 I: Interpretation,
236 T: LinkedDataResource<I, V>,
237 B: LinkedDataResource<I, V>,
238 L: LinkedDataResource<I, V>,
239 > LinkedDataResource<I, V> for Term<Id<T, B>, L>
240{
241 fn interpretation(
242 &self,
243 vocabulary: &mut V,
244 interpretation: &mut I,
245 ) -> ResourceInterpretation<I, V> {
246 match self {
247 Self::Id(id) => id.reference_interpretation(vocabulary, interpretation),
248 Self::Literal(l) => l.interpretation(vocabulary, interpretation),
249 }
250 }
251}
252
253impl<V: Vocabulary, I: Interpretation> LinkedDataResource<I, V> for rdf_types::Literal<V::Iri> {
254 fn interpretation(
255 &self,
256 _vocabulary: &mut V,
257 _interpretation: &mut I,
258 ) -> ResourceInterpretation<I, V> {
259 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(Term::Literal(
260 crate::RdfLiteralRef::Any(self.value.as_ref(), self.type_.as_ref()),
261 ))))
262 }
263}
264
265impl<I: Interpretation, V: Vocabulary, T: LinkedDataResource<I, V>> LinkedDataResource<I, V>
266 for Option<T>
267{
268 fn interpretation(
269 &self,
270 vocabulary: &mut V,
271 interpretation: &mut I,
272 ) -> ResourceInterpretation<I, V> {
273 match self {
274 Some(t) => t.interpretation(vocabulary, interpretation),
275 None => ResourceInterpretation::Uninterpreted(None),
276 }
277 }
278}