1use iref::{Iri, IriBuf, IriRef, IriRefBuf};
2use langtag::LangTagBuf;
3use rdf_types::vocabulary::{
4 self, BlankIdVocabulary, BlankIdVocabularyMut, IriVocabulary, IriVocabularyMut,
5};
6use rdf_types::{Generator, Id, LexicalTriple, LiteralType, Object, Subject, Term, Triple};
7use static_iref::iri;
8use std::collections::HashMap;
9
10const RDF_TYPE: &Iri = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
11const RDF_LIST: &Iri = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#List");
12const RDF_NIL: &Iri = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil");
13const RDF_FIRST: &Iri = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#first");
14const RDF_REST: &Iri = iri!("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest");
15const XSD_BOOLEAN: &Iri = iri!("http://www.w3.org/2001/XMLSchema#boolean");
16const XSD_INTEGER: &Iri = iri!("http://www.w3.org/2001/XMLSchema#integer");
17const XSD_DECIMAL: &Iri = iri!("http://www.w3.org/2001/XMLSchema#decimal");
18const XSD_DOUBLE: &Iri = iri!("http://www.w3.org/2001/XMLSchema#double");
19
20#[derive(Debug, thiserror::Error)]
21pub enum Error {
22 #[error("cannot resolve relative IRI <{0}>: no base IRI")]
23 NoBaseIri(IriRefBuf),
24
25 #[error("unknown IRI prefix `{0}`")]
26 UnknownPrefix(String),
27
28 #[error("invalid compact IRI suffix in `{prefix}:{invalid_suffix}`")]
29 InvalidCompactIriSuffix {
30 prefix: String,
31 iri: IriBuf,
32 invalid_suffix: String,
33 },
34}
35
36pub type BuildError<M> = (Box<Error>, M);
37
38pub type RdfId<V> = Id<<V as IriVocabulary>::Iri, <V as BlankIdVocabulary>::BlankId>;
39
40pub type MetaTriple<M, V = ()> = (
41 Triple<
42 (RdfId<V>, M),
43 (<V as IriVocabulary>::Iri, M),
44 (
45 Object<RdfId<V>, crate::RdfLiteral<M, <V as IriVocabulary>::Iri>>,
46 M,
47 ),
48 >,
49 M,
50);
51
52impl<M: Clone> crate::Document<M> {
53 pub fn build_meta_triples(
54 &self,
55 base_iri: Option<IriBuf>,
56 mut generator: impl Generator<()>,
57 ) -> Result<Vec<MetaTriple<M, ()>>, BuildError<M>> {
58 let mut triples = Vec::new();
59 let mut context = Context::new(base_iri, vocabulary::no_vocabulary_mut(), &mut generator);
60 self.build(&mut context, &mut triples)?;
61 Ok(triples)
62 }
63
64 pub fn build_meta_triples_with<V: RdfVocabulary + IriVocabularyMut + BlankIdVocabularyMut>(
65 &self,
66 base_iri: Option<V::Iri>,
67 vocabulary: &mut V,
68 mut generator: impl Generator<V>,
69 ) -> Result<Vec<MetaTriple<M, V>>, BuildError<M>>
70 where
71 V::Iri: Clone,
72 V::BlankId: Clone,
73 {
74 let mut triples = Vec::new();
75 let mut context = Context::new(base_iri, vocabulary, &mut generator);
76 self.build(&mut context, &mut triples)?;
77 Ok(triples)
78 }
79
80 pub fn build_lexical_triples(
81 &self,
82 base_iri: Option<IriBuf>,
83 mut generator: impl Generator<()>,
84 ) -> Result<Vec<LexicalTriple>, BuildError<M>> {
85 let triples = self.build_meta_triples(base_iri, &mut generator)?;
86
87 let triples = triples.into_iter().map(|triple| {
88 let o = match triple.0 .2 .0 {
89 Term::Id(id) => Term::Id::<rdf_types::Id, rdf_types::Literal>(id),
90 Term::Literal(literal) => Term::Literal(literal.into()),
91 };
92
93 LexicalTriple::new(triple.0 .0 .0, triple.0 .1 .0, o)
94 }).collect();
95
96 Ok(triples)
97 }
98}
99
100pub struct Context<'v, 'g, M, V: IriVocabulary, G> {
101 vocabulary: &'v mut V,
102 generator: &'g mut G,
103 base_iri: Option<V::Iri>,
104 prefixes: HashMap<String, (V::Iri, M)>,
105}
106
107impl<'v, 'g, M, V: IriVocabulary, G> Context<'v, 'g, M, V, G> {
108 pub fn new(base_iri: Option<V::Iri>, vocabulary: &'v mut V, generator: &'g mut G) -> Self {
109 Self {
110 vocabulary,
111 generator,
112 base_iri,
113 prefixes: HashMap::new(),
114 }
115 }
116
117 pub fn resolve_iri_ref(
118 &mut self,
119 (iri_ref, meta): (&IriRef, &M),
120 ) -> Result<V::Iri, BuildError<M>>
121 where
122 M: Clone,
123 V: IriVocabularyMut,
124 {
125 match &self.base_iri {
126 Some(current) => {
127 let iri = iri_ref.resolved(self.vocabulary.iri(current).unwrap());
128 Ok(self.vocabulary.insert(iri.as_iri()))
129 }
130 None => match iri_ref.as_iri() {
131 Some(iri) => Ok(self.vocabulary.insert(iri)),
132 None => Err((Box::new(Error::NoBaseIri(iri_ref.to_owned())), meta.clone())),
133 },
134 }
135 }
136
137 pub fn resolve_compact_iri(
138 &mut self,
139 prefix: (&str, &M),
140 suffix: (&str, &M),
141 meta: &M,
142 ) -> Result<V::Iri, BuildError<M>>
143 where
144 M: Clone,
145 V: IriVocabularyMut,
146 {
147 match self.prefixes.get(prefix.0) {
148 Some(iri) => {
149 let iri = self.vocabulary.iri(&iri.0).unwrap();
150 let mut buffer = iri.to_string();
151 buffer.push_str(suffix.0);
152 match Iri::new(&buffer) {
153 Ok(result) => Ok(self.vocabulary.insert(result)),
154 Err(_) => Err((
155 Box::new(Error::InvalidCompactIriSuffix {
156 prefix: prefix.0.to_owned(),
157 iri: iri.to_owned(),
158 invalid_suffix: suffix.0.to_owned(),
159 }),
160 meta.clone(),
161 )),
162 }
163 }
164 None => Err((
165 Box::new(Error::UnknownPrefix(prefix.0.to_owned())),
166 prefix.1.clone(),
167 )),
168 }
169 }
170
171 pub fn insert_prefix(&mut self, prefix: String, iri: V::Iri, meta: M) {
172 self.prefixes.insert(prefix, (iri, meta));
173 }
174}
175
176pub trait RdfVocabulary: IriVocabulary + BlankIdVocabulary {}
177
178impl<V> RdfVocabulary for V where V: IriVocabulary + BlankIdVocabulary {}
179
180pub trait Build<M, V: RdfVocabulary, G> {
181 fn build(
182 &self,
183 context: &mut Context<M, V, G>,
184 triples: &mut Vec<MetaTriple<M, V>>,
185 ) -> Result<(), BuildError<M>>;
186}
187
188impl<M: Clone, V: RdfVocabulary + IriVocabularyMut + BlankIdVocabularyMut, G: Generator<V>>
189 Build<M, V, G> for crate::Document<M>
190where
191 V::Iri: Clone,
192 V::BlankId: Clone,
193{
194 fn build(
195 &self,
196 context: &mut Context<M, V, G>,
197 triples: &mut Vec<MetaTriple<M, V>>,
198 ) -> Result<(), BuildError<M>> {
199 for statement in &self.statements {
200 match statement {
201 (crate::Statement::Directive(directive), meta) => match directive {
202 crate::Directive::Base(iri) | crate::Directive::SparqlBase(iri) => {
203 let iri_ref = (iri.0.as_iri_ref(), &iri.1);
204 context.base_iri = Some(context.resolve_iri_ref(iri_ref)?);
205 }
206 crate::Directive::Prefix(prefix, iri)
207 | crate::Directive::SparqlPrefix(prefix, iri) => {
208 let iri_ref = (iri.0.as_iri_ref(), &iri.1);
209 let iri = context.resolve_iri_ref(iri_ref)?;
210 context.insert_prefix(prefix.0.clone(), iri, meta.clone());
211 }
212 },
213 (crate::Statement::Triples(t), meta) => {
214 t.build(context, meta, triples)?;
215 }
216 }
217 }
218
219 Ok(())
220 }
221}
222
223impl<M: Clone> crate::Triples<M> {
224 fn build<V: RdfVocabulary + IriVocabularyMut + BlankIdVocabularyMut, G: Generator<V>>(
225 &self,
226 context: &mut Context<M, V, G>,
227 meta: &M,
228 triples: &mut Vec<MetaTriple<M, V>>,
229 ) -> Result<(), BuildError<M>>
230 where
231 V::Iri: Clone,
232 V::BlankId: Clone,
233 {
234 let subject = self.subject.build(context, triples)?;
235
236 for (po_list, _) in self.predicate_objects_list.0.iter() {
237 po_list.build(context, meta, &subject, triples)?;
238 }
239
240 Ok(())
241 }
242}
243
244impl<M: Clone> crate::PredicateObjects<M> {
245 fn build<V: RdfVocabulary + IriVocabularyMut + BlankIdVocabularyMut, G: Generator<V>>(
246 &self,
247 context: &mut Context<M, V, G>,
248 meta: &M,
249 subject: &(Subject<V::Iri, V::BlankId>, M),
250 triples: &mut Vec<MetaTriple<M, V>>,
251 ) -> Result<(), BuildError<M>>
252 where
253 V::Iri: Clone,
254 V::BlankId: Clone,
255 {
256 let predicate = self.verb.build(context, triples)?;
257
258 for o in &self.objects.0 .0 {
259 let object = o.build(context, triples)?;
260 triples.push((
261 Triple(subject.clone(), predicate.clone(), object),
262 meta.clone(),
263 ))
264 }
265
266 Ok(())
267 }
268}
269
270trait BuildFragment<M, V: RdfVocabulary + BlankIdVocabulary, G> {
271 type Target;
272
273 fn build(
274 &self,
275 context: &mut Context<M, V, G>,
276 triples: &mut Vec<MetaTriple<M, V>>,
277 ) -> Result<Self::Target, BuildError<M>>;
278}
279
280impl<T: BuildMetaFragment<M, V, G>, M: Clone, V: RdfVocabulary + BlankIdVocabulary, G>
281 BuildFragment<M, V, G> for (T, M)
282{
283 type Target = (T::Target, M);
284
285 fn build(
286 &self,
287 context: &mut Context<M, V, G>,
288 triples: &mut Vec<MetaTriple<M, V>>,
289 ) -> Result<Self::Target, BuildError<M>> {
290 Ok((self.0.build(context, &self.1, triples)?, self.1.clone()))
291 }
292}
293
294trait BuildMetaFragment<M, V: RdfVocabulary, G> {
295 type Target;
296
297 fn build(
298 &self,
299 context: &mut Context<M, V, G>,
300 meta: &M,
301 triples: &mut Vec<MetaTriple<M, V>>,
302 ) -> Result<Self::Target, BuildError<M>>;
303}
304
305impl<M: Clone, V: RdfVocabulary + IriVocabularyMut + BlankIdVocabulary, G>
306 BuildMetaFragment<M, V, G> for crate::Iri<M>
307{
308 type Target = V::Iri;
309
310 fn build(
311 &self,
312 context: &mut Context<M, V, G>,
313 meta: &M,
314 _triples: &mut Vec<MetaTriple<M, V>>,
315 ) -> Result<Self::Target, BuildError<M>> {
316 match self {
317 Self::IriRef(iri_ref) => context.resolve_iri_ref((iri_ref.as_iri_ref(), meta)),
318 Self::PrefixedName(prefix, suffix) => {
319 context.resolve_compact_iri((&prefix.0, &prefix.1), (&suffix.0, &suffix.1), meta)
320 }
321 }
322 }
323}
324
325impl<M: Clone, V: RdfVocabulary, G: Generator<V>> BuildMetaFragment<M, V, G> for crate::BlankNode<M>
326where
327 V: IriVocabularyMut + BlankIdVocabularyMut,
328 V::Iri: Clone,
329 V::BlankId: Clone,
330{
331 type Target = Subject<V::Iri, V::BlankId>;
332
333 fn build(
334 &self,
335 context: &mut Context<M, V, G>,
336 meta: &M,
337 triples: &mut Vec<MetaTriple<M, V>>,
338 ) -> Result<Self::Target, BuildError<M>> {
339 match self {
340 Self::Label(b) => Ok(Subject::Blank(context.vocabulary.insert_blank_id(b))),
341 Self::Anonymous(b_property_list) => {
342 let b = (context.generator.next(context.vocabulary), meta.clone());
343
344 for (predicate_objects, meta) in b_property_list.0.iter() {
345 predicate_objects.build(context, meta, &b, triples)?;
346 }
347
348 Ok(b.0)
349 }
350 }
351 }
352}
353
354impl<M: Clone, V: RdfVocabulary, G: Generator<V>> BuildMetaFragment<M, V, G> for crate::Subject<M>
355where
356 V: IriVocabularyMut + BlankIdVocabularyMut,
357 V::Iri: Clone,
358 V::BlankId: Clone,
359{
360 type Target = Subject<V::Iri, V::BlankId>;
361
362 fn build(
363 &self,
364 context: &mut Context<M, V, G>,
365 meta: &M,
366 triples: &mut Vec<MetaTriple<M, V>>,
367 ) -> Result<Self::Target, BuildError<M>> {
368 match self {
369 Self::Iri(iri) => Ok(Subject::Iri(iri.build(context, meta, triples)?)),
370 Self::BlankNode(b) => Ok(b.build(context, meta, triples)?),
371 Self::Collection(collection) => collection.build(context, meta, triples),
372 }
373 }
374}
375impl<M: Clone, V: RdfVocabulary, G: Generator<V>> BuildMetaFragment<M, V, G>
376 for crate::Collection<M>
377where
378 V: IriVocabularyMut + BlankIdVocabularyMut,
379 V::Iri: Clone,
380 V::BlankId: Clone,
381{
382 type Target = Subject<V::Iri, V::BlankId>;
383
384 fn build(
385 &self,
386 context: &mut Context<M, V, G>,
387 meta: &M,
388 triples: &mut Vec<MetaTriple<M, V>>,
389 ) -> Result<Self::Target, BuildError<M>> {
390 let mut head = Subject::Iri(context.vocabulary.insert(RDF_NIL));
391
392 for o in self.0.iter().rev() {
393 let item = o.build(context, triples)?;
394 let node = context.generator.next(context.vocabulary);
395
396 triples.push((
397 Triple(
398 (node.clone(), item.1.clone()),
399 (context.vocabulary.insert(RDF_TYPE), item.1.clone()),
400 (
401 Term::Id(Id::Iri(context.vocabulary.insert(RDF_LIST))),
402 item.1.clone(),
403 ),
404 ),
405 meta.clone(),
406 ));
407
408 triples.push((
409 Triple(
410 (node.clone(), item.1.clone()),
411 (context.vocabulary.insert(RDF_REST), item.1.clone()),
412 (head.into_term(), item.1.clone()),
413 ),
414 meta.clone(),
415 ));
416
417 triples.push((
418 Triple(
419 (node.clone(), item.1.clone()),
420 (context.vocabulary.insert(RDF_FIRST), item.1.clone()),
421 item,
422 ),
423 meta.clone(),
424 ));
425
426 head = node;
427 }
428
429 Ok(head)
430 }
431}
432
433impl<M: Clone, V: RdfVocabulary + IriVocabularyMut, G> BuildMetaFragment<M, V, G>
434 for crate::Verb<M>
435{
436 type Target = V::Iri;
437
438 fn build(
439 &self,
440 context: &mut Context<M, V, G>,
441 meta: &M,
442 triples: &mut Vec<MetaTriple<M, V>>,
443 ) -> Result<Self::Target, BuildError<M>> {
444 match self {
445 Self::A => Ok(context.vocabulary.insert(RDF_TYPE)),
446 Self::Predicate(i) => i.build(context, meta, triples),
447 }
448 }
449}
450
451impl<M: Clone, V: RdfVocabulary, G: Generator<V>> BuildMetaFragment<M, V, G> for crate::Object<M>
452where
453 V: IriVocabularyMut + BlankIdVocabularyMut,
454 V::Iri: Clone,
455 V::BlankId: Clone,
456{
457 type Target = Object<Id<V::Iri, V::BlankId>, crate::RdfLiteral<M, V::Iri>>;
458
459 fn build(
460 &self,
461 context: &mut Context<M, V, G>,
462 meta: &M,
463 triples: &mut Vec<MetaTriple<M, V>>,
464 ) -> Result<Self::Target, BuildError<M>> {
465 match self {
466 Self::Iri(iri) => Ok(Object::Id(Id::Iri(iri.build(context, meta, triples)?))),
467 Self::BlankNode(b) => Ok(b.build(context, meta, triples)?.into_term()),
468 Self::Collection(collection) => {
469 Ok(collection.build(context, meta, triples)?.into_term())
470 }
471 Self::Literal(literal) => Ok(Object::Literal(literal.build(context, meta, triples)?)),
472 }
473 }
474}
475
476impl<M: Clone, V: RdfVocabulary, G> BuildMetaFragment<M, V, G> for crate::Literal<M>
477where
478 V: IriVocabularyMut + BlankIdVocabulary,
479{
480 type Target = crate::RdfLiteral<M, V::Iri>;
481
482 fn build(
483 &self,
484 context: &mut Context<M, V, G>,
485 meta: &M,
486 triples: &mut Vec<MetaTriple<M, V>>,
487 ) -> Result<Self::Target, BuildError<M>> {
488 match self {
489 Self::Boolean(b) => b.build(context, meta, triples),
490 Self::Numeric(n) => n.build(context, meta, triples),
491 Self::Rdf(literal) => literal.build(context, meta, triples),
492 }
493 }
494}
495
496impl<M: Clone, V: RdfVocabulary, G> BuildMetaFragment<M, V, G> for bool
497where
498 V: IriVocabularyMut + BlankIdVocabulary,
499{
500 type Target = crate::RdfLiteral<M, V::Iri>;
501
502 fn build(
503 &self,
504 context: &mut Context<M, V, G>,
505 meta: &M,
506 _triples: &mut Vec<MetaTriple<M, V>>,
507 ) -> Result<Self::Target, BuildError<M>> {
508 let s = if *self { "true" } else { "false" };
509
510 Ok(crate::RdfLiteral {
511 value: (s.to_owned(), meta.clone()),
512 type_: (
513 LiteralType::Any(context.vocabulary.insert(XSD_BOOLEAN)),
514 meta.clone(),
515 ),
516 })
517 }
518}
519
520impl<M: Clone, V: RdfVocabulary, G> BuildMetaFragment<M, V, G> for crate::NumericLiteral
521where
522 V: IriVocabularyMut + BlankIdVocabulary,
523{
524 type Target = crate::RdfLiteral<M, V::Iri>;
525
526 fn build(
527 &self,
528 context: &mut Context<M, V, G>,
529 meta: &M,
530 _triples: &mut Vec<MetaTriple<M, V>>,
531 ) -> Result<Self::Target, BuildError<M>> {
532 let (s, ty) = match self {
533 Self::Integer(i) => (i.as_str(), XSD_INTEGER),
534 Self::Decimal(d) => (d.as_str(), XSD_DECIMAL),
535 Self::Double(d) => (d.as_str(), XSD_DOUBLE),
536 };
537
538 Ok(crate::RdfLiteral::new(
539 (s.to_owned(), meta.clone()),
540 (
541 LiteralType::Any(context.vocabulary.insert(ty)),
542 meta.clone(),
543 ),
544 ))
545 }
546}
547
548impl<M: Clone, V: RdfVocabulary, G> BuildMetaFragment<M, V, G> for crate::RdfLiteral<M>
549where
550 V: IriVocabularyMut + BlankIdVocabulary,
551{
552 type Target = crate::RdfLiteral<M, V::Iri>;
553
554 fn build(
555 &self,
556 context: &mut Context<M, V, G>,
557 _meta: &M,
558 triples: &mut Vec<MetaTriple<M, V>>,
559 ) -> Result<Self::Target, BuildError<M>> {
560 let type_ = match &self.type_ {
561 (LiteralType::Any(t), meta) => (
562 LiteralType::Any(t.build(context, meta, triples)?),
563 meta.clone(),
564 ),
565 (LiteralType::LangString(tag), meta) => (
566 LiteralType::LangString(tag.build(context, meta, triples)?),
567 meta.clone(),
568 ),
569 };
570
571 Ok(crate::RdfLiteral::new(self.value.clone(), type_))
572 }
573}
574
575impl<M: Clone, V: RdfVocabulary, G> BuildMetaFragment<M, V, G> for LangTagBuf {
576 type Target = LangTagBuf;
577
578 fn build(
579 &self,
580 _context: &mut Context<M, V, G>,
581 _meta: &M,
582 _triples: &mut Vec<MetaTriple<M, V>>,
583 ) -> Result<Self::Target, BuildError<M>> {
584 Ok(self.clone())
586 }
587}