sophia_turtle/parser/
turtle.rs1use rio_turtle::TurtleParser as RioTurtleParser;
3use sophia_api::parser::TripleParser;
4use sophia_iri::Iri;
5use sophia_rio::parser::*;
6use std::io::BufRead;
7
8#[derive(Clone, Debug, Default)]
10pub struct TurtleParser {
11 pub base: Option<Iri<String>>,
13}
14
15impl<B: BufRead> TripleParser<B> for TurtleParser {
16 type Source = StrictRioSource<RioTurtleParser<B>>;
17 fn parse(&self, data: B) -> Self::Source {
18 let base = self
19 .base
20 .clone()
21 .map(Iri::unwrap)
22 .map(oxiri::Iri::parse)
23 .map(Result::unwrap);
24 StrictRioSource(RioTurtleParser::new(data, base))
25 }
26}
27
28sophia_api::def_mod_functions_for_bufread_parser!(TurtleParser, TripleParser);
29
30#[cfg(test)]
35mod test {
36 use super::*;
37 use sophia_api::graph::Graph;
38 use sophia_api::ns::rdf;
39 use sophia_api::source::TripleSource;
40 use sophia_api::term::{SimpleTerm, TermKind};
41 use std::collections::HashSet;
42
43 type MyGraph = Vec<[SimpleTerm<'static>; 3]>;
44
45 #[test]
46 fn test_simple_turtle_string() -> std::result::Result<(), Box<dyn std::error::Error>> {
47 let turtle = r#"
48 @prefix : <http://example.org/ns/> .
49
50 <#me> :knows [ a :Person ; :name "Alice" ] {|
51 :since 2002 ;
52 |}.
53 "#;
54
55 let mut g = MyGraph::new();
56 let p = TurtleParser {
57 base: Some(Iri::new_unchecked("http://localhost/ex".to_string())),
58 };
59 let c = p.parse_str(turtle).add_to_graph(&mut g)?;
60 assert_eq!(c, 4);
61 assert_eq!(
62 g.triples_matching(
63 [Iri::new_unchecked("http://localhost/ex#me")],
64 [Iri::new_unchecked("http://example.org/ns/knows")],
65 TermKind::BlankNode,
66 )
67 .count(),
68 1
69 );
70 assert_eq!(
71 g.triples_matching(
72 TermKind::BlankNode,
73 [&rdf::type_],
74 [Iri::new_unchecked("http://example.org/ns/Person")],
75 )
76 .count(),
77 1
78 );
79 assert_eq!(
80 g.triples_matching(
81 TermKind::BlankNode,
82 [Iri::new_unchecked("http://example.org/ns/name")],
83 ["Alice"],
84 )
85 .count(),
86 1
87 );
88 assert_eq!(
89 g.triples_matching(
90 (
91 [Iri::new_unchecked("http://localhost/ex#me")],
92 [Iri::new_unchecked("http://example.org/ns/knows")],
93 TermKind::BlankNode,
94 ),
95 [Iri::new_unchecked("http://example.org/ns/since")],
96 [2002],
97 )
98 .count(),
99 1
100 );
101 assert_eq!(g.blank_nodes().collect::<HashSet<_>>().len(), 1);
102 Ok(())
103 }
104}