owlish/parser/
triple.rs

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}