oxigraph/io/
read.rs

1#![allow(deprecated)]
2
3//! Utilities to read RDF graphs and datasets.
4
5use crate::io::{DatasetFormat, GraphFormat};
6use crate::model::*;
7use oxrdfio::{RdfParseError, RdfParser, ReaderQuadParser};
8use std::io::Read;
9
10/// Parsers for RDF graph serialization formats.
11///
12/// It currently supports the following formats:
13/// * [N-Triples](https://www.w3.org/TR/n-triples/) ([`GraphFormat::NTriples`])
14/// * [Turtle](https://www.w3.org/TR/turtle/) ([`GraphFormat::Turtle`])
15/// * [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/) ([`GraphFormat::RdfXml`])
16///
17/// ```
18/// use oxigraph::io::{GraphFormat, GraphParser};
19///
20/// let file = "<http://example.com/s> <http://example.com/p> <http://example.com/o> .";
21///
22/// let parser = GraphParser::from_format(GraphFormat::NTriples);
23/// let triples = parser
24///     .read_triples(file.as_bytes())
25///     .collect::<Result<Vec<_>, _>>()?;
26///
27/// assert_eq!(triples.len(), 1);
28/// assert_eq!(triples[0].subject.to_string(), "<http://example.com/s>");
29/// # std::io::Result::Ok(())
30/// ```
31#[deprecated(note = "use RdfParser instead", since = "0.4.0")]
32pub struct GraphParser {
33    inner: RdfParser,
34}
35
36impl GraphParser {
37    /// Builds a parser for the given format.
38    #[inline]
39    pub fn from_format(format: GraphFormat) -> Self {
40        Self {
41            inner: RdfParser::from_format(format.into())
42                .without_named_graphs()
43                .rename_blank_nodes(),
44        }
45    }
46
47    /// Provides an IRI that could be used to resolve the file relative IRIs.
48    ///
49    /// ```
50    /// use oxigraph::io::{GraphFormat, GraphParser};
51    ///
52    /// let file = "</s> </p> </o> .";
53    ///
54    /// let parser =
55    ///     GraphParser::from_format(GraphFormat::Turtle).with_base_iri("http://example.com")?;
56    /// let triples = parser
57    ///     .read_triples(file.as_bytes())
58    ///     .collect::<Result<Vec<_>, _>>()?;
59    ///
60    /// assert_eq!(triples.len(), 1);
61    /// assert_eq!(triples[0].subject.to_string(), "<http://example.com/s>");
62    /// # Result::<_, Box<dyn std::error::Error>>::Ok(())
63    /// ```
64    #[inline]
65    pub fn with_base_iri(self, base_iri: impl Into<String>) -> Result<Self, IriParseError> {
66        Ok(Self {
67            inner: self.inner.with_base_iri(base_iri)?,
68        })
69    }
70
71    /// Executes the parsing itself on a [`Read`] implementation and returns an iterator of triples.
72    pub fn read_triples<R: Read>(self, reader: R) -> TripleReader<R> {
73        TripleReader {
74            parser: self.inner.for_reader(reader),
75        }
76    }
77}
78
79/// An iterator yielding read triples.
80/// Could be built using a [`GraphParser`].
81///
82/// ```
83/// use oxigraph::io::{GraphFormat, GraphParser};
84///
85/// let file = "<http://example.com/s> <http://example.com/p> <http://example.com/o> .";
86///
87/// let parser = GraphParser::from_format(GraphFormat::NTriples);
88/// let triples = parser
89///     .read_triples(file.as_bytes())
90///     .collect::<Result<Vec<_>, _>>()?;
91///
92/// assert_eq!(triples.len(), 1);
93/// assert_eq!(triples[0].subject.to_string(), "<http://example.com/s>");
94/// # std::io::Result::Ok(())
95/// ```
96#[must_use]
97pub struct TripleReader<R: Read> {
98    parser: ReaderQuadParser<R>,
99}
100
101impl<R: Read> Iterator for TripleReader<R> {
102    type Item = Result<Triple, RdfParseError>;
103
104    fn next(&mut self) -> Option<Self::Item> {
105        Some(self.parser.next()?.map(Into::into))
106    }
107}
108
109/// A parser for RDF dataset serialization formats.
110///
111/// It currently supports the following formats:
112/// * [N-Quads](https://www.w3.org/TR/n-quads/) ([`DatasetFormat::NQuads`])
113/// * [TriG](https://www.w3.org/TR/trig/) ([`DatasetFormat::TriG`])
114///
115/// ```
116/// use oxigraph::io::{DatasetFormat, DatasetParser};
117///
118/// let file = "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g> .";
119///
120/// let parser = DatasetParser::from_format(DatasetFormat::NQuads);
121/// let quads = parser.read_quads(file.as_bytes()).collect::<Result<Vec<_>,_>>()?;
122///
123/// assert_eq!(quads.len(), 1);
124/// assert_eq!(quads[0].subject.to_string(), "<http://example.com/s>");
125/// # std::io::Result::Ok(())
126/// ```
127#[deprecated(note = "use RdfParser instead", since = "0.4.0")]
128pub struct DatasetParser {
129    inner: RdfParser,
130}
131
132impl DatasetParser {
133    /// Builds a parser for the given format.
134    #[inline]
135    pub fn from_format(format: DatasetFormat) -> Self {
136        Self {
137            inner: RdfParser::from_format(format.into()).rename_blank_nodes(),
138        }
139    }
140
141    /// Provides an IRI that could be used to resolve the file relative IRIs.
142    ///
143    /// ```
144    /// use oxigraph::io::{DatasetFormat, DatasetParser};
145    ///
146    /// let file = "<g> { </s> </p> </o> }";
147    ///
148    /// let parser =
149    ///     DatasetParser::from_format(DatasetFormat::TriG).with_base_iri("http://example.com")?;
150    /// let triples = parser
151    ///     .read_quads(file.as_bytes())
152    ///     .collect::<Result<Vec<_>, _>>()?;
153    ///
154    /// assert_eq!(triples.len(), 1);
155    /// assert_eq!(triples[0].subject.to_string(), "<http://example.com/s>");
156    /// # Result::<_, Box<dyn std::error::Error>>::Ok(())
157    /// ```
158    #[inline]
159    pub fn with_base_iri(self, base_iri: impl Into<String>) -> Result<Self, IriParseError> {
160        Ok(Self {
161            inner: self.inner.with_base_iri(base_iri)?,
162        })
163    }
164
165    /// Executes the parsing itself on a [`Read`] implementation and returns an iterator of quads.
166    pub fn read_quads<R: Read>(self, reader: R) -> QuadReader<R> {
167        QuadReader {
168            parser: self.inner.for_reader(reader),
169        }
170    }
171}
172
173/// An iterator yielding read quads.
174/// Could be built using a [`DatasetParser`].
175///
176/// ```
177/// use oxigraph::io::{DatasetFormat, DatasetParser};
178///
179/// let file = "<http://example.com/s> <http://example.com/p> <http://example.com/o> <http://example.com/g> .";
180///
181/// let parser = DatasetParser::from_format(DatasetFormat::NQuads);
182/// let quads = parser.read_quads(file.as_bytes()).collect::<Result<Vec<_>,_>>()?;
183///
184/// assert_eq!(quads.len(), 1);
185/// assert_eq!(quads[0].subject.to_string(), "<http://example.com/s>");
186/// # std::io::Result::Ok(())
187/// ```
188#[must_use]
189pub struct QuadReader<R: Read> {
190    parser: ReaderQuadParser<R>,
191}
192
193impl<R: Read> Iterator for QuadReader<R> {
194    type Item = Result<Quad, RdfParseError>;
195
196    fn next(&mut self) -> Option<Self::Item> {
197        self.parser.next()
198    }
199}