sophia_turtle/parser/
nt.rs

1//! Adapter for the [N-Triples] parser from [RIO](https://github.com/Tpt/rio/blob/master/turtle/src/ntriples.rs)
2//!
3//! [N-Triples]: https://www.w3.org/TR/n-triples/
4use rio_turtle::NTriplesParser as RioNTParser;
5use sophia_api::parser::TripleParser;
6use sophia_rio::parser::*;
7use std::io::BufRead;
8
9/// N-Triples parser based on RIO.
10#[derive(Clone, Debug, Default)]
11pub struct NTriplesParser {}
12
13impl<B: BufRead> TripleParser<B> for NTriplesParser {
14    type Source = StrictRioSource<RioNTParser<B>>;
15    fn parse(&self, data: B) -> Self::Source {
16        StrictRioSource(RioNTParser::new(data))
17    }
18}
19
20sophia_api::def_mod_functions_for_bufread_parser!(NTriplesParser, TripleParser);
21
22// ---------------------------------------------------------------------------------
23//                                      tests
24// ---------------------------------------------------------------------------------
25
26#[cfg(test)]
27mod test {
28    use super::*;
29    use sophia_api::graph::Graph;
30    use sophia_api::ns::rdf;
31    use sophia_api::source::TripleSource;
32    use sophia_api::term::{SimpleTerm, TermKind};
33    use sophia_iri::Iri;
34    use std::collections::HashSet;
35
36    type MyGraph = Vec<[SimpleTerm<'static>; 3]>;
37
38    #[test]
39    fn test_simple_nt_string() -> std::result::Result<(), Box<dyn std::error::Error>> {
40        let nt = r#"
41            <http://localhost/ex#me> <http://example.org/ns/knows> _:b1.
42            _:b1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://example.org/ns/Person>.
43            _:b1 <http://example.org/ns/name> "Alice".
44            << <http://localhost/ex#me> <http://example.org/ns/knows> _:b1 >> <http://example.org/ns/since> "2002"^^<http://www.w3.org/2001/XMLSchema#integer>.
45        "#;
46
47        let mut g = MyGraph::new();
48        let p = NTriplesParser {};
49        let c = p.parse_str(nt).add_to_graph(&mut g)?;
50        assert_eq!(c, 4);
51        assert_eq!(
52            g.triples_matching(
53                [Iri::new_unchecked("http://localhost/ex#me")],
54                [Iri::new_unchecked("http://example.org/ns/knows")],
55                TermKind::BlankNode,
56            )
57            .count(),
58            1
59        );
60        assert_eq!(
61            g.triples_matching(
62                TermKind::BlankNode,
63                [&rdf::type_],
64                [Iri::new_unchecked("http://example.org/ns/Person")],
65            )
66            .count(),
67            1
68        );
69        assert_eq!(
70            g.triples_matching(
71                TermKind::BlankNode,
72                [Iri::new_unchecked("http://example.org/ns/name")],
73                ["Alice"],
74            )
75            .count(),
76            1
77        );
78        assert_eq!(
79            g.triples_matching(
80                (
81                    [Iri::new_unchecked("http://localhost/ex#me")],
82                    [Iri::new_unchecked("http://example.org/ns/knows")],
83                    TermKind::BlankNode,
84                ),
85                [Iri::new_unchecked("http://example.org/ns/since")],
86                [2002],
87            )
88            .count(),
89            1
90        );
91        assert_eq!(g.blank_nodes().collect::<HashSet<_>>().len(), 1);
92        Ok(())
93    }
94}