Makes SolutionsWriter input type broader

pull/190/head
Tpt 3 years ago
parent 5d95ae5d37
commit 34cc602e0b
  1. 23
      lib/sparesults/src/csv.rs
  2. 4
      lib/sparesults/src/json.rs
  3. 22
      lib/sparesults/src/lib.rs
  4. 6
      lib/sparesults/src/xml.rs
  5. 20
      lib/src/sparql/model.rs

@ -32,11 +32,11 @@ impl<W: Write> CsvSolutionsWriter<W> {
pub fn write<'a>(
&mut self,
solution: impl IntoIterator<Item = (&'a Variable, &'a Term)>,
solution: impl IntoIterator<Item = (VariableRef<'a>, TermRef<'a>)>,
) -> io::Result<()> {
let mut values = vec![None; self.variables.len()];
for (variable, value) in solution {
if let Some(position) = self.variables.iter().position(|v| v == variable) {
if let Some(position) = self.variables.iter().position(|v| *v == variable) {
values[position] = Some(value);
}
}
@ -122,11 +122,11 @@ impl<W: Write> TsvSolutionsWriter<W> {
pub fn write<'a>(
&mut self,
solution: impl IntoIterator<Item = (&'a Variable, &'a Term)>,
solution: impl IntoIterator<Item = (VariableRef<'a>, TermRef<'a>)>,
) -> io::Result<()> {
let mut values = vec![None; self.variables.len()];
for (variable, value) in solution {
if let Some(position) = self.variables.iter().position(|v| v == variable) {
if let Some(position) = self.variables.iter().position(|v| *v == variable) {
values[position] = Some(value);
}
}
@ -259,7 +259,6 @@ impl<R: BufRead> TsvSolutionsReader<R> {
#[cfg(test)]
mod tests {
use super::*;
use crate::QuerySolution;
use std::io::Cursor;
use std::rc::Rc;
use std::str;
@ -313,7 +312,12 @@ mod tests {
let mut writer = CsvSolutionsWriter::start(Vec::new(), variables.clone())?;
let variables = Rc::new(variables);
for solution in solutions {
writer.write(QuerySolution::from((variables.clone(), solution)).iter())?;
writer.write(
variables
.iter()
.zip(&solution)
.filter_map(|(v, s)| s.as_ref().map(|s| (v.as_ref(), s.as_ref()))),
)?;
}
let result = writer.finish();
assert_eq!(str::from_utf8(&result).unwrap(), "x,literal\r\nhttp://example/x,String\r\nhttp://example/x,\"String-with-dquote\"\"\"\r\n_:b0,Blank node\r\n,Missing 'x'\r\n,\r\nhttp://example/x,\r\n_:b1,String-with-lang\r\n_:b1,123");
@ -326,7 +330,12 @@ mod tests {
let mut writer = TsvSolutionsWriter::start(Vec::new(), variables.clone())?;
let variables = Rc::new(variables);
for solution in solutions {
writer.write(QuerySolution::from((variables.clone(), solution)).iter())?;
writer.write(
variables
.iter()
.zip(&solution)
.filter_map(|(v, s)| s.as_ref().map(|s| (v.as_ref(), s.as_ref()))),
)?;
}
let result = writer.finish();
assert_eq!(str::from_utf8(&result).unwrap(), "?x\t?literal\n<http://example/x>\t\"String\"\n<http://example/x>\t\"String-with-dquote\\\"\"\n_:b0\t\"Blank node\"\n\t\"Missing 'x'\"\n\t\n<http://example/x>\t\n_:b1\t\"String-with-lang\"@en\n_:b1\t123");

@ -50,13 +50,13 @@ impl<W: Write> JsonSolutionsWriter<W> {
pub fn write<'a>(
&mut self,
solution: impl IntoIterator<Item = (&'a Variable, &'a Term)>,
solution: impl IntoIterator<Item = (VariableRef<'a>, TermRef<'a>)>,
) -> io::Result<()> {
self.writer.write_event(JsonEvent::StartObject)?;
for (variable, value) in solution {
self.writer
.write_event(JsonEvent::ObjectKey(variable.as_str()))?;
write_json_term(value.as_ref(), &mut self.writer)?;
write_json_term(value, &mut self.writer)?;
}
self.writer.write_event(JsonEvent::EndObject)?;
Ok(())

@ -22,8 +22,7 @@ pub use crate::error::{ParseError, SyntaxError};
use crate::json::*;
pub use crate::solution::QuerySolution;
use crate::xml::*;
use oxrdf::Term;
pub use oxrdf::Variable;
use oxrdf::{TermRef, Variable, VariableRef};
use std::io::{self, BufRead, Write};
use std::rc::Rc;
@ -342,7 +341,7 @@ impl<R: BufRead> Iterator for SolutionsReader<R> {
/// Example in JSON (the API is the same for XML and TSV):
/// ```
/// use sparesults::{QueryResultsFormat, QueryResultsSerializer};
/// use oxrdf::{Literal, Variable};
/// use oxrdf::{LiteralRef, Variable, VariableRef};
/// use std::iter::once;
///
/// let json_serializer = QueryResultsSerializer::from_format(QueryResultsFormat::Json);
@ -355,7 +354,7 @@ impl<R: BufRead> Iterator for SolutionsReader<R> {
/// // solutions
/// let mut buffer = Vec::new();
/// let mut writer = json_serializer.solutions_writer(&mut buffer, vec![Variable::new_unchecked("foo"), Variable::new_unchecked("bar")])?;
/// writer.write(once((&Variable::new_unchecked("foo"), &Literal::from("test").into())))?;
/// writer.write(once((VariableRef::new_unchecked("foo"), LiteralRef::from("test"))))?;
/// writer.finish()?;
/// assert_eq!(buffer, b"{\"head\":{\"vars\":[\"foo\",\"bar\"]},\"results\":{\"bindings\":[{\"foo\":{\"type\":\"literal\",\"value\":\"test\"}}]}}");
/// # std::io::Result::Ok(())
@ -398,13 +397,13 @@ impl QueryResultsSerializer {
/// Example in XML (the API is the same for JSON and TSV):
/// ```
/// use sparesults::{QueryResultsFormat, QueryResultsSerializer};
/// use oxrdf::{Literal, Variable};
/// use oxrdf::{LiteralRef, Variable, VariableRef};
/// use std::iter::once;
///
/// let json_serializer = QueryResultsSerializer::from_format(QueryResultsFormat::Xml);
/// let mut buffer = Vec::new();
/// let mut writer = json_serializer.solutions_writer(&mut buffer, vec![Variable::new_unchecked("foo"), Variable::new_unchecked("bar")])?;
/// writer.write(once((&Variable::new_unchecked("foo"), &Literal::from("test").into())))?;
/// writer.write(once((VariableRef::new_unchecked("foo"), LiteralRef::from("test"))))?;
/// writer.finish()?;
/// assert_eq!(buffer, b"<?xml version=\"1.0\"?><sparql xmlns=\"http://www.w3.org/2005/sparql-results#\"><head><variable name=\"foo\"/><variable name=\"bar\"/></head><results><result><binding name=\"foo\"><literal>test</literal></binding></result></results></sparql>");
/// # std::io::Result::Ok(())
@ -441,13 +440,13 @@ impl QueryResultsSerializer {
/// Example in TSV (the API is the same for JSON and XML):
/// ```
/// use sparesults::{QueryResultsFormat, QueryResultsSerializer};
/// use oxrdf::{Literal, Variable};
/// use oxrdf::{LiteralRef, Variable, VariableRef};
/// use std::iter::once;
///
/// let json_serializer = QueryResultsSerializer::from_format(QueryResultsFormat::Tsv);
/// let mut buffer = Vec::new();
/// let mut writer = json_serializer.solutions_writer(&mut buffer, vec![Variable::new_unchecked("foo"), Variable::new_unchecked("bar")])?;
/// writer.write(once((&Variable::new_unchecked("foo"), &Literal::from("test").into())))?;
/// writer.write(once((VariableRef::new_unchecked("foo"), LiteralRef::from("test"))))?;
/// writer.finish()?;
/// assert_eq!(buffer, b"?foo\t?bar\n\"test\"\t");
/// # std::io::Result::Ok(())
@ -470,13 +469,13 @@ impl<W: Write> SolutionsWriter<W> {
/// Example in JSON (the API is the same for XML and TSV):
/// ```
/// use sparesults::{QueryResultsFormat, QueryResultsSerializer, QuerySolution};
/// use oxrdf::{Literal, Variable};
/// use oxrdf::{Literal, LiteralRef, Variable, VariableRef};
/// use std::iter::once;
///
/// let json_serializer = QueryResultsSerializer::from_format(QueryResultsFormat::Json);
/// let mut buffer = Vec::new();
/// let mut writer = json_serializer.solutions_writer(&mut buffer, vec![Variable::new_unchecked("foo"), Variable::new_unchecked("bar")])?;
/// writer.write(once((&Variable::new_unchecked("foo"), &Literal::from("test").into())))?;
/// writer.write(once((VariableRef::new_unchecked("foo"), LiteralRef::from("test"))))?;
/// writer.write(&QuerySolution::from((vec![Variable::new_unchecked("bar")], vec![Some(Literal::from("test").into())])))?;
/// writer.finish()?;
/// assert_eq!(buffer, b"{\"head\":{\"vars\":[\"foo\",\"bar\"]},\"results\":{\"bindings\":[{\"foo\":{\"type\":\"literal\",\"value\":\"test\"}},{\"bar\":{\"type\":\"literal\",\"value\":\"test\"}}]}}");
@ -484,8 +483,9 @@ impl<W: Write> SolutionsWriter<W> {
/// ```
pub fn write<'a>(
&mut self,
solution: impl IntoIterator<Item = (&'a Variable, &'a Term)>,
solution: impl IntoIterator<Item = (impl Into<VariableRef<'a>>, impl Into<TermRef<'a>>)>,
) -> io::Result<()> {
let solution = solution.into_iter().map(|(v, s)| (v.into(), s.into()));
match &mut self.formatter {
SolutionsWriterKind::Xml(writer) => writer.write(solution),
SolutionsWriterKind::Json(writer) => writer.write(solution),

@ -61,14 +61,14 @@ impl<W: Write> XmlSolutionsWriter<W> {
pub fn write<'a>(
&mut self,
solution: impl IntoIterator<Item = (&'a Variable, &'a Term)>,
solution: impl IntoIterator<Item = (VariableRef<'a>, TermRef<'a>)>,
) -> io::Result<()> {
self.do_write(solution).map_err(map_xml_error)
}
fn do_write<'a>(
&mut self,
solution: impl IntoIterator<Item = (&'a Variable, &'a Term)>,
solution: impl IntoIterator<Item = (VariableRef<'a>, TermRef<'a>)>,
) -> Result<(), quick_xml::Error> {
self.writer
.write_event(Event::Start(BytesStart::borrowed_name(b"result")))?;
@ -76,7 +76,7 @@ impl<W: Write> XmlSolutionsWriter<W> {
let mut binding_tag = BytesStart::borrowed_name(b"binding");
binding_tag.push_attribute(("name", variable.as_str()));
self.writer.write_event(Event::Start(binding_tag))?;
write_xml_term(value.as_ref(), &mut self.writer)?;
write_xml_term(value, &mut self.writer)?;
self.writer
.write_event(Event::End(BytesEnd::borrowed(b"binding")))?;
}

@ -2,7 +2,7 @@ use crate::io::GraphFormat;
use crate::io::GraphSerializer;
use crate::model::*;
use crate::sparql::error::EvaluationError;
use oxrdf::Variable;
use oxrdf::{Variable, VariableRef};
pub use sparesults::QuerySolution;
use sparesults::{
QueryResultsFormat, QueryResultsParser, QueryResultsReader, QueryResultsSerializer,
@ -66,17 +66,19 @@ impl QueryResults {
writer.finish()?;
}
QueryResults::Graph(triples) => {
let s = Variable::new_unchecked("subject");
let p = Variable::new_unchecked("predicate");
let o = Variable::new_unchecked("object");
let mut writer =
serializer.solutions_writer(writer, vec![s.clone(), p.clone(), o.clone()])?;
let s = VariableRef::new_unchecked("subject");
let p = VariableRef::new_unchecked("predicate");
let o = VariableRef::new_unchecked("object");
let mut writer = serializer.solutions_writer(
writer,
vec![s.into_owned(), p.into_owned(), o.into_owned()],
)?;
for triple in triples {
let triple = triple?;
writer.write([
(&s, &triple.subject.into()),
(&p, &triple.predicate.into()),
(&o, &triple.object),
(s, &triple.subject.into()),
(p, &triple.predicate.into()),
(o, &triple.object),
])?;
}
writer.finish()?;

Loading…
Cancel
Save