1use educe::Educe;
2use iri_rs::IriBuf;
3use rdfx::{
4 BlankId, BlankIdBuf, Id, Interpretation, Literal, LocalTerm, Term,
5 interpretation::{ReverseInterpretation, ReverseLocalInterpretation},
6};
7use std::fmt;
8
9use crate::{BorrowedRdfTerm, CowRdfTerm, OwnedRdfTerm};
10
11#[derive(Educe)]
13#[educe(Debug(bound = "I::Resource: fmt::Debug"))]
14pub enum ResourceInterpretation<'a, I: Interpretation> {
15 Interpreted(&'a I::Resource),
17
18 Uninterpreted(Option<CowRdfTerm<'a>>),
23}
24
25impl<'a, I: Interpretation> ResourceInterpretation<'a, I> {
26 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>> {
36 match self {
37 Self::Uninterpreted(t) => t.as_ref(),
38 _ => None,
39 }
40 }
41
42 pub fn into_lexical_representation(self, interpretation: &'a I) -> Option<CowRdfTerm<'a>>
45 where
46 I: ReverseInterpretation + ReverseLocalInterpretation,
47 {
48 match self {
49 Self::Interpreted(r) => {
50 if let Some(i) = interpretation.iris_of(r).next() {
51 return Some(CowRdfTerm::Owned(OwnedRdfTerm::Iri(i.into_owned())));
52 }
53
54 if let Some(l) = interpretation.literals_of(r).next() {
55 return Some(CowRdfTerm::Owned(
56 OwnedRdfTerm::Literal(
57 crate::RdfLiteralRef::Any(&l.value.clone(), l.type_.as_ref())
58 .into_owned(),
59 )
60 .into_self_owned(),
61 ));
62 }
63
64 if let Some(b) = interpretation.blank_ids_of(r).next() {
65 return Some(CowRdfTerm::Owned(OwnedRdfTerm::BlankId(b.into_owned())));
66 }
67
68 None
69 }
70 Self::Uninterpreted(t) => t,
71 }
72 }
73}
74
75impl OwnedRdfTerm {
76 fn into_self_owned(self) -> Self {
77 self
78 }
79}
80
81pub trait LinkedDataResourceRef<'a, I: Interpretation = ()> {
83 fn interpretation_ref(&self, interpretation: &mut I) -> ResourceInterpretation<'a, I>;
85}
86
87pub trait LinkedDataResource<I: Interpretation = ()> {
89 fn interpretation(&self, interpretation: &mut I) -> ResourceInterpretation<'_, I>;
92
93 fn lexical_representation<'a>(&'a self, interpretation: &'a mut I) -> Option<CowRdfTerm<'a>>
95 where
96 I: ReverseInterpretation + ReverseLocalInterpretation,
97 {
98 match self.interpretation(interpretation) {
100 ResourceInterpretation::Interpreted(_) => {
101 self.interpretation(interpretation)
103 .into_lexical_representation(interpretation)
104 }
105 ResourceInterpretation::Uninterpreted(t) => t,
106 }
107 }
108
109 fn reference_interpretation(&self, interpretation: &mut I) -> ResourceInterpretation<'_, I> {
112 self.interpretation(interpretation)
113 }
114}
115
116impl<I: Interpretation, T: ?Sized + LinkedDataResource<I>> LinkedDataResource<I> for &T {
117 fn interpretation(&self, interpretation: &mut I) -> ResourceInterpretation<'_, I> {
118 T::interpretation(self, interpretation)
119 }
120}
121
122impl<I: Interpretation, T: ?Sized + LinkedDataResource<I>> LinkedDataResource<I> for Box<T> {
123 fn interpretation(&self, interpretation: &mut I) -> ResourceInterpretation<'_, I> {
124 T::interpretation(self, interpretation)
125 }
126}
127
128impl<I: Interpretation> LinkedDataResource<I> for () {
129 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
130 ResourceInterpretation::Uninterpreted(None)
131 }
132}
133
134pub struct Anonymous;
139
140impl<I: Interpretation> LinkedDataResource<I> for Anonymous {
141 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
142 ResourceInterpretation::Uninterpreted(None)
143 }
144}
145
146impl<I: Interpretation> LinkedDataResource<I> for IriBuf {
147 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
148 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(BorrowedRdfTerm::Iri(
149 self.as_ref(),
150 ))))
151 }
152}
153
154impl<I: Interpretation> LinkedDataResource<I> for iri_rs::Iri<&str> {
155 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
156 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(BorrowedRdfTerm::Iri(
157 *self,
158 ))))
159 }
160}
161
162impl<I: Interpretation> LinkedDataResource<I> for BlankId {
163 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
164 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(BorrowedRdfTerm::BlankId(
165 self,
166 ))))
167 }
168}
169
170impl<I: Interpretation> LinkedDataResource<I> for BlankIdBuf {
171 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
172 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(BorrowedRdfTerm::BlankId(
173 self.as_ref(),
174 ))))
175 }
176}
177
178impl<I: Interpretation> LinkedDataResource<I> for Id {
179 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
180 match self {
181 Self::Iri(i) => ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(
182 BorrowedRdfTerm::Iri(i.as_ref()),
183 ))),
184 Self::BlankId(b) => ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(
185 BorrowedRdfTerm::BlankId(b),
186 ))),
187 }
188 }
189}
190
191impl<I: Interpretation> LinkedDataResource<I> for Term {
192 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
193 match self {
194 Self::Iri(i) => ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(
195 BorrowedRdfTerm::Iri(i.as_ref()),
196 ))),
197 Self::Literal(l) => ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(
198 BorrowedRdfTerm::Literal(crate::RdfLiteralRef::Any(&l.value, l.type_.as_ref())),
199 ))),
200 }
201 }
202}
203
204impl<I: Interpretation> LinkedDataResource<I> for LocalTerm {
205 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
206 match self {
207 Self::BlankId(b) => ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(
208 BorrowedRdfTerm::BlankId(b),
209 ))),
210 Self::Named(Term::Iri(i)) => ResourceInterpretation::Uninterpreted(Some(
211 CowRdfTerm::Borrowed(BorrowedRdfTerm::Iri(i.as_ref())),
212 )),
213 Self::Named(Term::Literal(l)) => {
214 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(
215 BorrowedRdfTerm::Literal(crate::RdfLiteralRef::Any(&l.value, l.type_.as_ref())),
216 )))
217 }
218 Self::Triple(_) => ResourceInterpretation::Uninterpreted(None),
219 }
220 }
221}
222
223impl<I: Interpretation> LinkedDataResource<I> for Literal {
224 fn interpretation(&self, _interpretation: &mut I) -> ResourceInterpretation<'_, I> {
225 ResourceInterpretation::Uninterpreted(Some(CowRdfTerm::Borrowed(BorrowedRdfTerm::Literal(
226 crate::RdfLiteralRef::Any(self.value.as_str(), self.type_.as_ref()),
227 ))))
228 }
229}
230
231impl<I: Interpretation, T: LinkedDataResource<I>> LinkedDataResource<I> for Option<T> {
232 fn interpretation(&self, interpretation: &mut I) -> ResourceInterpretation<'_, I> {
233 match self {
234 Some(t) => t.interpretation(interpretation),
235 None => ResourceInterpretation::Uninterpreted(None),
236 }
237 }
238}