owlish 0.28.0

OWL 2 implementation with wasm support and turtle parsing
Documentation
use harriet::triple_production::{RdfObject, RdfPredicate, RdfSubject, RdfTriple};
use serde::{Deserialize, Serialize};

use crate::owl::{Literal, LiteralOrIRI, IRI};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Triple {
    subject: IRI,
    predicate: IRI,
    value: LiteralOrIRI,
}

pub fn parse_triple(ttl: &str) -> Option<Triple> {
    let mut ttl_string = ttl.to_string();
    if !ttl.ends_with('.') {
        ttl_string = format!("{} .", ttl)
    }
    let ttl = harriet::TurtleDocument::parse_full(&ttl_string);
    if ttl.is_err() {
        eprintln!("{:?}", ttl.unwrap_err());
        return None;
    }
    let ttl = ttl.unwrap();

    if let Ok(triples) = harriet::triple_production::TripleProducer::produce_for_document(&ttl) {
        if let Some(t) = triples.into_iter().next() {
            return Triple::from_rdf(t);
        }
    }
    None
}

impl Triple {
    fn from_rdf(t: RdfTriple<'_>) -> Option<Self> {
        if let RdfSubject::IRI(sub) = t.subject {
            if let Ok(sub) = IRI::new(&sub.iri) {
                let RdfPredicate::IRI(pred) = t.predicate;

                if let Ok(pred) = IRI::new(&pred.iri) {
                    match t.object {
                        RdfObject::IRI(obj) => {
                            if let Ok(obj) = IRI::new(&obj.iri) {
                                return Some(Self {
                                    subject: sub,
                                    predicate: pred,
                                    value: obj.into(),
                                });
                            }
                        }
                        RdfObject::Literal(lit) => {
                            return Some(Self {
                                subject: sub,
                                predicate: pred,
                                value: Literal::from(lit.lexical_form.to_string()).into(),
                            });
                        }
                        RdfObject::BlankNode(_) => return None,
                    }
                }
            }
        }
        None
    }
}

#[cfg(test)]
mod tests {
    use crate::owl::IRI;

    use super::{parse_triple, Triple};

    #[test]
    fn tests() {
        let ttl = r#"<http://field33.com/a#1234> <http://field33.com/ontologies/business_object/Number> "1234""#;
        let t = parse_triple(ttl);
        assert_eq!(
            t,
            Some(Triple {
                subject: IRI::new("http://field33.com/a#1234").unwrap(),
                predicate: IRI::new("http://field33.com/ontologies/business_object/Number")
                    .unwrap(),
                value: "1234".into()
            })
        )
    }
}