1use harriet::triple_production::{RdfObject, RdfPredicate, RdfSubject, RdfTriple};
2use serde::{Deserialize, Serialize};
3
4use crate::owl::{Literal, LiteralOrIRI, IRI};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
7pub struct Triple {
8 subject: IRI,
9 predicate: IRI,
10 value: LiteralOrIRI,
11}
12
13pub fn parse_triple(ttl: &str) -> Option<Triple> {
14 let mut ttl_string = ttl.to_string();
15 if !ttl.ends_with('.') {
16 ttl_string = format!("{} .", ttl)
17 }
18 let ttl = harriet::TurtleDocument::parse_full(&ttl_string);
19 if ttl.is_err() {
20 eprintln!("{:?}", ttl.unwrap_err());
21 return None;
22 }
23 let ttl = ttl.unwrap();
24
25 if let Ok(triples) = harriet::triple_production::TripleProducer::produce_for_document(&ttl) {
26 if let Some(t) = triples.into_iter().next() {
27 return Triple::from_rdf(t);
28 }
29 }
30 None
31}
32
33impl Triple {
34 fn from_rdf(t: RdfTriple<'_>) -> Option<Self> {
35 if let RdfSubject::IRI(sub) = t.subject {
36 if let Ok(sub) = IRI::new(&sub.iri) {
37 let RdfPredicate::IRI(pred) = t.predicate;
38
39 if let Ok(pred) = IRI::new(&pred.iri) {
40 match t.object {
41 RdfObject::IRI(obj) => {
42 if let Ok(obj) = IRI::new(&obj.iri) {
43 return Some(Self {
44 subject: sub,
45 predicate: pred,
46 value: obj.into(),
47 });
48 }
49 }
50 RdfObject::Literal(lit) => {
51 return Some(Self {
52 subject: sub,
53 predicate: pred,
54 value: Literal::from(lit.lexical_form.to_string()).into(),
55 });
56 }
57 RdfObject::BlankNode(_) => return None,
58 }
59 }
60 }
61 }
62 None
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use crate::owl::IRI;
69
70 use super::{parse_triple, Triple};
71
72 #[test]
73 fn tests() {
74 let ttl = r#"<http://field33.com/a#1234> <http://field33.com/ontologies/business_object/Number> "1234""#;
75 let t = parse_triple(ttl);
76 assert_eq!(
77 t,
78 Some(Triple {
79 subject: IRI::new("http://field33.com/a#1234").unwrap(),
80 predicate: IRI::new("http://field33.com/ontologies/business_object/Number")
81 .unwrap(),
82 value: "1234".into()
83 })
84 )
85 }
86}