1pub mod export;
7pub mod owl;
8pub mod rdf;
9
10use nibli_engine::NibliEngine;
11
12pub fn import_turtle(engine: &NibliEngine, turtle_text: &str) -> Result<usize, String> {
20 let triples = rdf::parse_turtle(turtle_text)?;
21 owl::import_owl_classes(engine, &triples)
22}
23
24pub fn import_triples_raw(engine: &NibliEngine, turtle_text: &str) -> Result<usize, String> {
29 let triples = rdf::parse_turtle(turtle_text)?;
30 let mut count = 0;
31 for triple in &triples {
32 let rel = triple.predicate.local_name().to_string();
33 let args = vec![
34 term_to_logical(&triple.subject),
35 term_to_logical(&triple.object),
36 ];
37 engine
38 .assert_fact_direct(rel, args)
39 .map_err(|e| e.to_string())?;
40 count += 1;
41 }
42 Ok(count)
43}
44
45pub fn export_facts(engine: &NibliEngine) -> Result<String, String> {
47 export::export_fact_labels(engine)
48}
49
50fn term_to_logical(term: &rdf::Term) -> nibli_engine::EngineLogicalTerm {
51 match term {
52 rdf::Term::Iri(_) => {
53 nibli_engine::EngineLogicalTerm::Constant(term.local_name().to_string())
54 }
55 rdf::Term::StringLiteral(s) => nibli_engine::EngineLogicalTerm::Constant(s.clone()),
56 rdf::Term::NumericLiteral(n) => nibli_engine::EngineLogicalTerm::Number(*n),
57 }
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_import_simple_triple() {
66 let engine = NibliEngine::new();
67 let turtle =
68 r#"<http://example.org/adam> <http://example.org/likes> <http://example.org/bob> ."#;
69 let count = import_triples_raw(&engine, turtle).unwrap();
70 assert_eq!(count, 1);
71 let facts = engine.list_facts().unwrap();
72 assert!(!facts.is_empty());
73 }
74
75 #[test]
76 fn test_import_owl_class_hierarchy() {
77 let engine = NibliEngine::new();
78 let turtle = r#"
79<http://example.org/Dog> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://example.org/Animal> .
80<http://example.org/adam> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/Dog> .
81"#;
82 let count = import_turtle(&engine, turtle).unwrap();
83 assert_eq!(count, 2); }
85
86 #[test]
87 fn test_import_numeric_literal() {
88 let engine = NibliEngine::new();
89 let turtle = r#"<http://example.org/adam> <http://example.org/age> "42"^^<http://www.w3.org/2001/XMLSchema#integer> ."#;
90 let count = import_triples_raw(&engine, turtle).unwrap();
91 assert_eq!(count, 1);
92 }
93
94 #[test]
95 fn test_import_with_prefix() {
96 let engine = NibliEngine::new();
97 let turtle = r#"
98@prefix ex: <http://example.org/> .
99ex:adam ex:likes ex:bob .
100"#;
101 let count = import_triples_raw(&engine, turtle).unwrap();
102 assert_eq!(count, 1);
103 }
104
105 #[test]
106 fn test_export_roundtrip() {
107 let engine = NibliEngine::new();
108 engine
109 .assert_fact_direct(
110 "likes".to_string(),
111 vec![
112 nibli_engine::EngineLogicalTerm::Constant("adam".to_string()),
113 nibli_engine::EngineLogicalTerm::Constant("bob".to_string()),
114 ],
115 )
116 .unwrap();
117 let exported = export_facts(&engine).unwrap();
118 assert!(exported.contains("likes"));
119 }
120}