Upgrades json-event-parser

pull/641/head
Tpt 1 year ago committed by Thomas Tanon
parent 5e3a2fc89d
commit dbb39d867a
  1. 4
      Cargo.lock
  2. 2
      lib/Cargo.toml
  3. 2
      lib/sparesults/Cargo.toml
  4. 25
      lib/sparesults/src/error.rs
  5. 205
      lib/sparesults/src/json.rs
  6. 18
      lib/src/sparql/eval.rs
  7. 16
      lib/src/sparql/mod.rs
  8. 2
      lints/test_debian_compatibility.py

4
Cargo.lock generated

@ -786,9 +786,9 @@ dependencies = [
[[package]] [[package]]
name = "json-event-parser" name = "json-event-parser"
version = "0.1.1" version = "0.2.0-alpha.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f12e624eaeb74accb9bb48f01cb071427f68115aaafa5689acb372d7e22977" checksum = "20a2ad11b373ee8f1d5f9b0632b148a6dc65cf1faa8b2a99c89cbe70411e31a2"
[[package]] [[package]]
name = "kernel32-sys" name = "kernel32-sys"

@ -28,7 +28,7 @@ rocksdb-debug = []
[dependencies] [dependencies]
digest = "0.10" digest = "0.10"
hex = "0.4" hex = "0.4"
json-event-parser = "0.1" json-event-parser = "0.2.0-alpha.1"
md-5 = "0.10" md-5 = "0.10"
oxilangtag = "0.1" oxilangtag = "0.1"
oxiri = "0.2" oxiri = "0.2"

@ -19,7 +19,7 @@ default = []
rdf-star = ["oxrdf/rdf-star"] rdf-star = ["oxrdf/rdf-star"]
[dependencies] [dependencies]
json-event-parser = "0.1" json-event-parser = "0.2.0-alpha.1"
memchr = "2.5" memchr = "2.5"
oxrdf = { version = "0.2.0-alpha.1-dev", path="../oxrdf" } oxrdf = { version = "0.2.0-alpha.1-dev", path="../oxrdf" }
quick-xml = ">=0.29, <0.31" quick-xml = ">=0.29, <0.31"

@ -56,6 +56,15 @@ impl From<ParseError> for io::Error {
} }
} }
impl From<json_event_parser::ParseError> for ParseError {
fn from(error: json_event_parser::ParseError) -> Self {
match error {
json_event_parser::ParseError::Syntax(error) => SyntaxError::from(error).into(),
json_event_parser::ParseError::Io(error) => error.into(),
}
}
}
impl From<quick_xml::Error> for ParseError { impl From<quick_xml::Error> for ParseError {
#[inline] #[inline]
fn from(error: quick_xml::Error) -> Self { fn from(error: quick_xml::Error) -> Self {
@ -79,6 +88,7 @@ pub struct SyntaxError {
#[derive(Debug)] #[derive(Debug)]
pub(crate) enum SyntaxErrorKind { pub(crate) enum SyntaxErrorKind {
Json(json_event_parser::SyntaxError),
Xml(quick_xml::Error), Xml(quick_xml::Error),
Term { error: TermParseError, term: String }, Term { error: TermParseError, term: String },
Msg { msg: String }, Msg { msg: String },
@ -98,6 +108,7 @@ impl fmt::Display for SyntaxError {
#[inline] #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self.inner { match &self.inner {
SyntaxErrorKind::Json(e) => e.fmt(f),
SyntaxErrorKind::Xml(e) => e.fmt(f), SyntaxErrorKind::Xml(e) => e.fmt(f),
SyntaxErrorKind::Term { error, term } => write!(f, "{error}: {term}"), SyntaxErrorKind::Term { error, term } => write!(f, "{error}: {term}"),
SyntaxErrorKind::Msg { msg } => f.write_str(msg), SyntaxErrorKind::Msg { msg } => f.write_str(msg),
@ -109,6 +120,7 @@ impl Error for SyntaxError {
#[inline] #[inline]
fn source(&self) -> Option<&(dyn Error + 'static)> { fn source(&self) -> Option<&(dyn Error + 'static)> {
match &self.inner { match &self.inner {
SyntaxErrorKind::Json(e) => Some(e),
SyntaxErrorKind::Xml(e) => Some(e), SyntaxErrorKind::Xml(e) => Some(e),
SyntaxErrorKind::Term { error, .. } => Some(error), SyntaxErrorKind::Term { error, .. } => Some(error),
SyntaxErrorKind::Msg { .. } => None, SyntaxErrorKind::Msg { .. } => None,
@ -120,6 +132,7 @@ impl From<SyntaxError> for io::Error {
#[inline] #[inline]
fn from(error: SyntaxError) -> Self { fn from(error: SyntaxError) -> Self {
match error.inner { match error.inner {
SyntaxErrorKind::Json(error) => Self::new(io::ErrorKind::InvalidData, error),
SyntaxErrorKind::Xml(error) => match error { SyntaxErrorKind::Xml(error) => match error {
quick_xml::Error::Io(error) => match Arc::try_unwrap(error) { quick_xml::Error::Io(error) => match Arc::try_unwrap(error) {
Ok(error) => error, Ok(error) => error,
@ -130,10 +143,16 @@ impl From<SyntaxError> for io::Error {
} }
_ => Self::new(io::ErrorKind::InvalidData, error), _ => Self::new(io::ErrorKind::InvalidData, error),
}, },
SyntaxErrorKind::Term { .. } => { SyntaxErrorKind::Term { .. } => Self::new(io::ErrorKind::InvalidData, error),
Self::new(io::ErrorKind::InvalidData, error.to_string())
}
SyntaxErrorKind::Msg { msg } => Self::new(io::ErrorKind::InvalidData, msg), SyntaxErrorKind::Msg { msg } => Self::new(io::ErrorKind::InvalidData, msg),
} }
} }
} }
impl From<json_event_parser::SyntaxError> for SyntaxError {
fn from(error: json_event_parser::SyntaxError) -> Self {
Self {
inner: SyntaxErrorKind::Json(error),
}
}
}

@ -1,50 +1,50 @@
//! Implementation of [SPARQL Query Results JSON Format](https://www.w3.org/TR/sparql11-results-json/) //! Implementation of [SPARQL Query Results JSON Format](https://www.w3.org/TR/sparql11-results-json/)
use crate::error::{ParseError, SyntaxError}; use crate::error::{ParseError, SyntaxError};
use json_event_parser::{JsonEvent, JsonReader, JsonWriter}; use json_event_parser::{FromReadJsonReader, JsonEvent, ToWriteJsonWriter};
use oxrdf::vocab::rdf; use oxrdf::vocab::rdf;
use oxrdf::Variable; use oxrdf::Variable;
use oxrdf::*; use oxrdf::*;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::io::{self, BufRead, Write}; use std::io::{self, Read, Write};
use std::mem::take; use std::mem::take;
/// This limit is set in order to avoid stack overflow error when parsing nested triples due to too many recursive calls. /// This limit is set in order to avoid stack overflow error when parsing nested triples due to too many recursive calls.
/// The actual limit value is a wet finger compromise between not failing to parse valid files and avoiding to trigger stack overflow errors. /// The actual limit value is a wet finger compromise between not failing to parse valid files and avoiding to trigger stack overflow errors.
const MAX_NUMBER_OF_NESTED_TRIPLES: usize = 128; const MAX_NUMBER_OF_NESTED_TRIPLES: usize = 128;
pub fn write_boolean_json_result<W: Write>(sink: W, value: bool) -> io::Result<W> { pub fn write_boolean_json_result<W: Write>(write: W, value: bool) -> io::Result<W> {
let mut writer = JsonWriter::from_writer(sink); let mut writer = ToWriteJsonWriter::new(write);
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("head"))?; writer.write_event(JsonEvent::ObjectKey("head".into()))?;
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
writer.write_event(JsonEvent::ObjectKey("boolean"))?; writer.write_event(JsonEvent::ObjectKey("boolean".into()))?;
writer.write_event(JsonEvent::Boolean(value))?; writer.write_event(JsonEvent::Boolean(value))?;
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
Ok(writer.into_inner()) writer.finish()
} }
pub struct JsonSolutionsWriter<W: Write> { pub struct JsonSolutionsWriter<W: Write> {
writer: JsonWriter<W>, writer: ToWriteJsonWriter<W>,
} }
impl<W: Write> JsonSolutionsWriter<W> { impl<W: Write> JsonSolutionsWriter<W> {
pub fn start(sink: W, variables: &[Variable]) -> io::Result<Self> { pub fn start(write: W, variables: &[Variable]) -> io::Result<Self> {
let mut writer = JsonWriter::from_writer(sink); let mut writer = ToWriteJsonWriter::new(write);
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("head"))?; writer.write_event(JsonEvent::ObjectKey("head".into()))?;
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("vars"))?; writer.write_event(JsonEvent::ObjectKey("vars".into()))?;
writer.write_event(JsonEvent::StartArray)?; writer.write_event(JsonEvent::StartArray)?;
for variable in variables { for variable in variables {
writer.write_event(JsonEvent::String(variable.as_str()))?; writer.write_event(JsonEvent::String(variable.as_str().into()))?;
} }
writer.write_event(JsonEvent::EndArray)?; writer.write_event(JsonEvent::EndArray)?;
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
writer.write_event(JsonEvent::ObjectKey("results"))?; writer.write_event(JsonEvent::ObjectKey("results".into()))?;
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("bindings"))?; writer.write_event(JsonEvent::ObjectKey("bindings".into()))?;
writer.write_event(JsonEvent::StartArray)?; writer.write_event(JsonEvent::StartArray)?;
Ok(Self { writer }) Ok(Self { writer })
} }
@ -56,7 +56,7 @@ impl<W: Write> JsonSolutionsWriter<W> {
self.writer.write_event(JsonEvent::StartObject)?; self.writer.write_event(JsonEvent::StartObject)?;
for (variable, value) in solution { for (variable, value) in solution {
self.writer self.writer
.write_event(JsonEvent::ObjectKey(variable.as_str()))?; .write_event(JsonEvent::ObjectKey(variable.as_str().into()))?;
write_json_term(value, &mut self.writer)?; write_json_term(value, &mut self.writer)?;
} }
self.writer.write_event(JsonEvent::EndObject)?; self.writer.write_event(JsonEvent::EndObject)?;
@ -67,55 +67,58 @@ impl<W: Write> JsonSolutionsWriter<W> {
self.writer.write_event(JsonEvent::EndArray)?; self.writer.write_event(JsonEvent::EndArray)?;
self.writer.write_event(JsonEvent::EndObject)?; self.writer.write_event(JsonEvent::EndObject)?;
self.writer.write_event(JsonEvent::EndObject)?; self.writer.write_event(JsonEvent::EndObject)?;
Ok(self.writer.into_inner()) self.writer.finish()
} }
} }
fn write_json_term(term: TermRef<'_>, writer: &mut JsonWriter<impl Write>) -> io::Result<()> { fn write_json_term(
term: TermRef<'_>,
writer: &mut ToWriteJsonWriter<impl Write>,
) -> io::Result<()> {
match term { match term {
TermRef::NamedNode(uri) => { TermRef::NamedNode(uri) => {
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("type"))?; writer.write_event(JsonEvent::ObjectKey("type".into()))?;
writer.write_event(JsonEvent::String("uri"))?; writer.write_event(JsonEvent::String("uri".into()))?;
writer.write_event(JsonEvent::ObjectKey("value"))?; writer.write_event(JsonEvent::ObjectKey("value".into()))?;
writer.write_event(JsonEvent::String(uri.as_str()))?; writer.write_event(JsonEvent::String(uri.as_str().into()))?;
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
} }
TermRef::BlankNode(bnode) => { TermRef::BlankNode(bnode) => {
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("type"))?; writer.write_event(JsonEvent::ObjectKey("type".into()))?;
writer.write_event(JsonEvent::String("bnode"))?; writer.write_event(JsonEvent::String("bnode".into()))?;
writer.write_event(JsonEvent::ObjectKey("value"))?; writer.write_event(JsonEvent::ObjectKey("value".into()))?;
writer.write_event(JsonEvent::String(bnode.as_str()))?; writer.write_event(JsonEvent::String(bnode.as_str().into()))?;
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
} }
TermRef::Literal(literal) => { TermRef::Literal(literal) => {
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("type"))?; writer.write_event(JsonEvent::ObjectKey("type".into()))?;
writer.write_event(JsonEvent::String("literal"))?; writer.write_event(JsonEvent::String("literal".into()))?;
writer.write_event(JsonEvent::ObjectKey("value"))?; writer.write_event(JsonEvent::ObjectKey("value".into()))?;
writer.write_event(JsonEvent::String(literal.value()))?; writer.write_event(JsonEvent::String(literal.value().into()))?;
if let Some(language) = literal.language() { if let Some(language) = literal.language() {
writer.write_event(JsonEvent::ObjectKey("xml:lang"))?; writer.write_event(JsonEvent::ObjectKey("xml:lang".into()))?;
writer.write_event(JsonEvent::String(language))?; writer.write_event(JsonEvent::String(language.into()))?;
} else if !literal.is_plain() { } else if !literal.is_plain() {
writer.write_event(JsonEvent::ObjectKey("datatype"))?; writer.write_event(JsonEvent::ObjectKey("datatype".into()))?;
writer.write_event(JsonEvent::String(literal.datatype().as_str()))?; writer.write_event(JsonEvent::String(literal.datatype().as_str().into()))?;
} }
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
} }
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
TermRef::Triple(triple) => { TermRef::Triple(triple) => {
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("type"))?; writer.write_event(JsonEvent::ObjectKey("type".into()))?;
writer.write_event(JsonEvent::String("triple"))?; writer.write_event(JsonEvent::String("triple".into()))?;
writer.write_event(JsonEvent::ObjectKey("value"))?; writer.write_event(JsonEvent::ObjectKey("value".into()))?;
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("subject"))?; writer.write_event(JsonEvent::ObjectKey("subject".into()))?;
write_json_term(triple.subject.as_ref().into(), writer)?; write_json_term(triple.subject.as_ref().into(), writer)?;
writer.write_event(JsonEvent::ObjectKey("predicate"))?; writer.write_event(JsonEvent::ObjectKey("predicate".into()))?;
write_json_term(triple.predicate.as_ref().into(), writer)?; write_json_term(triple.predicate.as_ref().into(), writer)?;
writer.write_event(JsonEvent::ObjectKey("object"))?; writer.write_event(JsonEvent::ObjectKey("object".into()))?;
write_json_term(triple.object.as_ref(), writer)?; write_json_term(triple.object.as_ref(), writer)?;
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
writer.write_event(JsonEvent::EndObject)?; writer.write_event(JsonEvent::EndObject)?;
@ -124,7 +127,7 @@ fn write_json_term(term: TermRef<'_>, writer: &mut JsonWriter<impl Write>) -> io
Ok(()) Ok(())
} }
pub enum JsonQueryResultsReader<R: BufRead> { pub enum JsonQueryResultsReader<R: Read> {
Solutions { Solutions {
variables: Vec<Variable>, variables: Vec<Variable>,
solutions: JsonSolutionsReader<R>, solutions: JsonSolutionsReader<R>,
@ -132,24 +135,23 @@ pub enum JsonQueryResultsReader<R: BufRead> {
Boolean(bool), Boolean(bool),
} }
impl<R: BufRead> JsonQueryResultsReader<R> { impl<R: Read> JsonQueryResultsReader<R> {
pub fn read(source: R) -> Result<Self, ParseError> { pub fn read(read: R) -> Result<Self, ParseError> {
let mut reader = JsonReader::from_reader(source); let mut reader = FromReadJsonReader::new(read);
let mut buffer = Vec::default();
let mut variables = None; let mut variables = None;
let mut buffered_bindings: Option<Vec<_>> = None; let mut buffered_bindings: Option<Vec<_>> = None;
let mut output_iter = None; let mut output_iter = None;
if reader.read_event(&mut buffer)? != JsonEvent::StartObject { if reader.read_next_event()? != JsonEvent::StartObject {
return Err(SyntaxError::msg("SPARQL JSON results should be an object").into()); return Err(SyntaxError::msg("SPARQL JSON results should be an object").into());
} }
loop { loop {
let event = reader.read_event(&mut buffer)?; let event = reader.read_next_event()?;
match event { match event {
JsonEvent::ObjectKey(key) => match key { JsonEvent::ObjectKey(key) => match key.as_ref() {
"head" => { "head" => {
let extracted_variables = read_head(&mut reader, &mut buffer)?; let extracted_variables = read_head(&mut reader)?;
if let Some(buffered_bindings) = buffered_bindings.take() { if let Some(buffered_bindings) = buffered_bindings.take() {
let mut mapping = BTreeMap::default(); let mut mapping = BTreeMap::default();
for (i, var) in extracted_variables.iter().enumerate() { for (i, var) in extracted_variables.iter().enumerate() {
@ -169,13 +171,13 @@ impl<R: BufRead> JsonQueryResultsReader<R> {
} }
} }
"results" => { "results" => {
if reader.read_event(&mut buffer)? != JsonEvent::StartObject { if reader.read_next_event()? != JsonEvent::StartObject {
return Err(SyntaxError::msg("'results' should be an object").into()); return Err(SyntaxError::msg("'results' should be an object").into());
} }
loop { loop {
match reader.read_event(&mut buffer)? { match reader.read_next_event()? {
JsonEvent::ObjectKey("bindings") => break, // Found JsonEvent::ObjectKey(k) if k == "bindings" => break, // Found
JsonEvent::ObjectKey(_) => ignore_value(&mut reader, &mut buffer)?, JsonEvent::ObjectKey(_) => ignore_value(&mut reader)?,
_ => { _ => {
return Err(SyntaxError::msg( return Err(SyntaxError::msg(
"'results' should contain a 'bindings' key", "'results' should contain a 'bindings' key",
@ -184,7 +186,7 @@ impl<R: BufRead> JsonQueryResultsReader<R> {
} }
} }
} }
if reader.read_event(&mut buffer)? != JsonEvent::StartArray { if reader.read_next_event()? != JsonEvent::StartArray {
return Err(SyntaxError::msg("'bindings' should be an object").into()); return Err(SyntaxError::msg("'bindings' should be an object").into());
} }
if let Some(variables) = variables { if let Some(variables) = variables {
@ -195,7 +197,7 @@ impl<R: BufRead> JsonQueryResultsReader<R> {
return Ok(Self::Solutions { return Ok(Self::Solutions {
variables, variables,
solutions: JsonSolutionsReader { solutions: JsonSolutionsReader {
kind: JsonSolutionsReaderKind::Streaming { reader, buffer }, kind: JsonSolutionsReaderKind::Streaming { reader },
mapping, mapping,
}, },
}); });
@ -205,7 +207,7 @@ impl<R: BufRead> JsonQueryResultsReader<R> {
let mut variables = Vec::new(); let mut variables = Vec::new();
let mut values = Vec::new(); let mut values = Vec::new();
loop { loop {
match reader.read_event(&mut buffer)? { match reader.read_next_event()? {
JsonEvent::StartObject => (), JsonEvent::StartObject => (),
JsonEvent::EndObject => { JsonEvent::EndObject => {
bindings.push((take(&mut variables), take(&mut values))); bindings.push((take(&mut variables), take(&mut values)));
@ -215,8 +217,8 @@ impl<R: BufRead> JsonQueryResultsReader<R> {
break; break;
} }
JsonEvent::ObjectKey(key) => { JsonEvent::ObjectKey(key) => {
variables.push(key.to_owned()); variables.push(key.into_owned());
values.push(read_value(&mut reader, &mut buffer, 0)?); values.push(read_value(&mut reader, 0)?);
} }
_ => { _ => {
return Err( return Err(
@ -227,7 +229,7 @@ impl<R: BufRead> JsonQueryResultsReader<R> {
} }
} }
"boolean" => { "boolean" => {
return if let JsonEvent::Boolean(v) = reader.read_event(&mut buffer)? { return if let JsonEvent::Boolean(v) = reader.read_next_event()? {
Ok(Self::Boolean(v)) Ok(Self::Boolean(v))
} else { } else {
Err(SyntaxError::msg("Unexpected boolean value").into()) Err(SyntaxError::msg("Unexpected boolean value").into())
@ -257,38 +259,37 @@ impl<R: BufRead> JsonQueryResultsReader<R> {
} }
} }
pub struct JsonSolutionsReader<R: BufRead> { pub struct JsonSolutionsReader<R: Read> {
mapping: BTreeMap<String, usize>, mapping: BTreeMap<String, usize>,
kind: JsonSolutionsReaderKind<R>, kind: JsonSolutionsReaderKind<R>,
} }
enum JsonSolutionsReaderKind<R: BufRead> { enum JsonSolutionsReaderKind<R: Read> {
Streaming { Streaming {
reader: JsonReader<R>, reader: FromReadJsonReader<R>,
buffer: Vec<u8>,
}, },
Buffered { Buffered {
bindings: std::vec::IntoIter<(Vec<String>, Vec<Term>)>, bindings: std::vec::IntoIter<(Vec<String>, Vec<Term>)>,
}, },
} }
impl<R: BufRead> JsonSolutionsReader<R> { impl<R: Read> JsonSolutionsReader<R> {
pub fn read_next(&mut self) -> Result<Option<Vec<Option<Term>>>, ParseError> { pub fn read_next(&mut self) -> Result<Option<Vec<Option<Term>>>, ParseError> {
match &mut self.kind { match &mut self.kind {
JsonSolutionsReaderKind::Streaming { reader, buffer } => { JsonSolutionsReaderKind::Streaming { reader } => {
let mut new_bindings = vec![None; self.mapping.len()]; let mut new_bindings = vec![None; self.mapping.len()];
loop { loop {
match reader.read_event(buffer)? { match reader.read_next_event()? {
JsonEvent::StartObject => (), JsonEvent::StartObject => (),
JsonEvent::EndObject => return Ok(Some(new_bindings)), JsonEvent::EndObject => return Ok(Some(new_bindings)),
JsonEvent::EndArray | JsonEvent::Eof => return Ok(None), JsonEvent::EndArray | JsonEvent::Eof => return Ok(None),
JsonEvent::ObjectKey(key) => { JsonEvent::ObjectKey(key) => {
let k = *self.mapping.get(key).ok_or_else(|| { let k = *self.mapping.get(key.as_ref()).ok_or_else(|| {
SyntaxError::msg(format!( SyntaxError::msg(format!(
"The variable {key} has not been defined in the header" "The variable {key} has not been defined in the header"
)) ))
})?; })?;
new_bindings[k] = Some(read_value(reader, buffer, 0)?) new_bindings[k] = Some(read_value(reader, 0)?)
} }
_ => return Err(SyntaxError::msg("Invalid result serialization").into()), _ => return Err(SyntaxError::msg("Invalid result serialization").into()),
} }
@ -314,9 +315,8 @@ impl<R: BufRead> JsonSolutionsReader<R> {
} }
} }
fn read_value<R: BufRead>( fn read_value<R: Read>(
reader: &mut JsonReader<R>, reader: &mut FromReadJsonReader<R>,
buffer: &mut Vec<u8>,
number_of_recursive_calls: usize, number_of_recursive_calls: usize,
) -> Result<Term, ParseError> { ) -> Result<Term, ParseError> {
enum Type { enum Type {
@ -351,28 +351,29 @@ fn read_value<R: BufRead>(
let mut predicate = None; let mut predicate = None;
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
let mut object = None; let mut object = None;
if reader.read_event(buffer)? != JsonEvent::StartObject { if reader.read_next_event()? != JsonEvent::StartObject {
return Err(SyntaxError::msg("Term serializations should be an object").into()); return Err(SyntaxError::msg("Term serializations should be an object").into());
} }
loop { loop {
match reader.read_event(buffer)? { #[allow(unsafe_code)]
JsonEvent::ObjectKey(key) => match key { // SAFETY: Borrow checker workaround https://github.com/rust-lang/rust/issues/70255
let next_event = unsafe {
let r: *mut FromReadJsonReader<R> = reader;
&mut *r
}
.read_next_event()?;
match next_event {
JsonEvent::ObjectKey(key) => match key.as_ref() {
"type" => state = Some(State::Type), "type" => state = Some(State::Type),
"value" => state = Some(State::Value), "value" => state = Some(State::Value),
"xml:lang" => state = Some(State::Lang), "xml:lang" => state = Some(State::Lang),
"datatype" => state = Some(State::Datatype), "datatype" => state = Some(State::Datatype),
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
"subject" => { "subject" => subject = Some(read_value(reader, number_of_recursive_calls + 1)?),
subject = Some(read_value(reader, buffer, number_of_recursive_calls + 1)?)
}
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
"predicate" => { "predicate" => predicate = Some(read_value(reader, number_of_recursive_calls + 1)?),
predicate = Some(read_value(reader, buffer, number_of_recursive_calls + 1)?)
}
#[cfg(feature = "rdf-star")] #[cfg(feature = "rdf-star")]
"object" => { "object" => object = Some(read_value(reader, number_of_recursive_calls + 1)?),
object = Some(read_value(reader, buffer, number_of_recursive_calls + 1)?)
}
_ => { _ => {
return Err(SyntaxError::msg(format!( return Err(SyntaxError::msg(format!(
"Unexpected key in term serialization: '{key}'" "Unexpected key in term serialization: '{key}'"
@ -389,7 +390,7 @@ fn read_value<R: BufRead>(
} }
JsonEvent::String(s) => match state { JsonEvent::String(s) => match state {
Some(State::Type) => { Some(State::Type) => {
match s { match s.as_ref() {
"uri" => t = Some(Type::Uri), "uri" => t = Some(Type::Uri),
"bnode" => t = Some(Type::BNode), "bnode" => t = Some(Type::BNode),
"literal" | "typed-literal" => t = Some(Type::Literal), "literal" | "typed-literal" => t = Some(Type::Literal),
@ -404,11 +405,11 @@ fn read_value<R: BufRead>(
state = None; state = None;
} }
Some(State::Value) => { Some(State::Value) => {
value = Some(s.to_owned()); value = Some(s.into_owned());
state = None; state = None;
} }
Some(State::Lang) => { Some(State::Lang) => {
lang = Some(s.to_owned()); lang = Some(s.into_owned());
state = None; state = None;
} }
Some(State::Datatype) => { Some(State::Datatype) => {
@ -458,7 +459,7 @@ fn read_value<R: BufRead>(
)).into()) )).into())
} }
} }
Literal::new_language_tagged_literal(value, &lang).map_err(|e| { Literal::new_language_tagged_literal(value, &*lang).map_err(|e| {
SyntaxError::msg(format!("Invalid xml:lang value '{lang}': {e}")) SyntaxError::msg(format!("Invalid xml:lang value '{lang}': {e}"))
})? })?
} }
@ -511,25 +512,22 @@ fn read_value<R: BufRead>(
} }
} }
fn read_head<R: BufRead>( fn read_head<R: Read>(reader: &mut FromReadJsonReader<R>) -> Result<Vec<Variable>, ParseError> {
reader: &mut JsonReader<R>, if reader.read_next_event()? != JsonEvent::StartObject {
buffer: &mut Vec<u8>,
) -> Result<Vec<Variable>, ParseError> {
if reader.read_event(buffer)? != JsonEvent::StartObject {
return Err(SyntaxError::msg("head should be an object").into()); return Err(SyntaxError::msg("head should be an object").into());
} }
let mut variables = Vec::new(); let mut variables = Vec::new();
loop { loop {
match reader.read_event(buffer)? { match reader.read_next_event()? {
JsonEvent::ObjectKey(key) => match key { JsonEvent::ObjectKey(key) => match key.as_ref() {
"vars" => { "vars" => {
if reader.read_event(buffer)? != JsonEvent::StartArray { if reader.read_next_event()? != JsonEvent::StartArray {
return Err(SyntaxError::msg("Variable list should be an array").into()); return Err(SyntaxError::msg("Variable list should be an array").into());
} }
loop { loop {
match reader.read_event(buffer)? { match reader.read_next_event()? {
JsonEvent::String(s) => { JsonEvent::String(s) => {
let new_var = Variable::new(s).map_err(|e| { let new_var = Variable::new(s.as_ref()).map_err(|e| {
SyntaxError::msg(format!( SyntaxError::msg(format!(
"Invalid variable declaration '{s}': {e}" "Invalid variable declaration '{s}': {e}"
)) ))
@ -552,11 +550,11 @@ fn read_head<R: BufRead>(
} }
} }
"link" => { "link" => {
if reader.read_event(buffer)? != JsonEvent::StartArray { if reader.read_next_event()? != JsonEvent::StartArray {
return Err(SyntaxError::msg("Variable list should be an array").into()); return Err(SyntaxError::msg("Variable list should be an array").into());
} }
loop { loop {
match reader.read_event(buffer)? { match reader.read_next_event()? {
JsonEvent::String(_) => (), JsonEvent::String(_) => (),
JsonEvent::EndArray => break, JsonEvent::EndArray => break,
_ => { _ => {
@ -565,7 +563,7 @@ fn read_head<R: BufRead>(
} }
} }
} }
_ => ignore_value(reader, buffer)?, _ => ignore_value(reader)?,
}, },
JsonEvent::EndObject => return Ok(variables), JsonEvent::EndObject => return Ok(variables),
_ => return Err(SyntaxError::msg("Invalid head serialization").into()), _ => return Err(SyntaxError::msg("Invalid head serialization").into()),
@ -573,13 +571,10 @@ fn read_head<R: BufRead>(
} }
} }
fn ignore_value<R: BufRead>( fn ignore_value<R: Read>(reader: &mut FromReadJsonReader<R>) -> Result<(), ParseError> {
reader: &mut JsonReader<R>,
buffer: &mut Vec<u8>,
) -> Result<(), ParseError> {
let mut nesting = 0; let mut nesting = 0;
loop { loop {
match reader.read_event(buffer)? { match reader.read_next_event()? {
JsonEvent::Boolean(_) JsonEvent::Boolean(_)
| JsonEvent::Null | JsonEvent::Null
| JsonEvent::Number(_) | JsonEvent::Number(_)

@ -8,7 +8,7 @@ use crate::sparql::service::ServiceHandler;
use crate::storage::numeric_encoder::*; use crate::storage::numeric_encoder::*;
use crate::storage::small_string::SmallString; use crate::storage::small_string::SmallString;
use digest::Digest; use digest::Digest;
use json_event_parser::{JsonEvent, JsonWriter}; use json_event_parser::{JsonEvent, ToWriteJsonWriter};
use md5::Md5; use md5::Md5;
use oxilangtag::LanguageTag; use oxilangtag::LanguageTag;
use oxiri::Iri; use oxiri::Iri;
@ -5676,21 +5676,21 @@ pub struct EvalNodeWithStats {
impl EvalNodeWithStats { impl EvalNodeWithStats {
pub fn json_node( pub fn json_node(
&self, &self,
writer: &mut JsonWriter<impl io::Write>, writer: &mut ToWriteJsonWriter<impl io::Write>,
with_stats: bool, with_stats: bool,
) -> io::Result<()> { ) -> io::Result<()> {
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
writer.write_event(JsonEvent::ObjectKey("name"))?; writer.write_event(JsonEvent::ObjectKey("name".into()))?;
writer.write_event(JsonEvent::String(&self.label))?; writer.write_event(JsonEvent::String((&self.label).into()))?;
if with_stats { if with_stats {
writer.write_event(JsonEvent::ObjectKey("number of results"))?; writer.write_event(JsonEvent::ObjectKey("number of results".into()))?;
writer.write_event(JsonEvent::Number(&self.exec_count.get().to_string()))?; writer.write_event(JsonEvent::Number(self.exec_count.get().to_string().into()))?;
if let Some(duration) = self.exec_duration.get() { if let Some(duration) = self.exec_duration.get() {
writer.write_event(JsonEvent::ObjectKey("duration in seconds"))?; writer.write_event(JsonEvent::ObjectKey("duration in seconds".into()))?;
writer.write_event(JsonEvent::Number(&duration.as_seconds().to_string()))?; writer.write_event(JsonEvent::Number(duration.as_seconds().to_string().into()))?;
} }
} }
writer.write_event(JsonEvent::ObjectKey("children"))?; writer.write_event(JsonEvent::ObjectKey("children".into()))?;
writer.write_event(JsonEvent::StartArray)?; writer.write_event(JsonEvent::StartArray)?;
for child in &self.children { for child in &self.children {
child.json_node(writer, with_stats)?; child.json_node(writer, with_stats)?;

@ -22,7 +22,7 @@ pub use crate::sparql::service::ServiceHandler;
use crate::sparql::service::{EmptyServiceHandler, ErrorConversionServiceHandler}; use crate::sparql::service::{EmptyServiceHandler, ErrorConversionServiceHandler};
pub(crate) use crate::sparql::update::evaluate_update; pub(crate) use crate::sparql::update::evaluate_update;
use crate::storage::StorageReader; use crate::storage::StorageReader;
use json_event_parser::{JsonEvent, JsonWriter}; use json_event_parser::{JsonEvent, ToWriteJsonWriter};
pub use oxrdf::{Variable, VariableNameParseError}; pub use oxrdf::{Variable, VariableNameParseError};
use oxsdatatypes::{DayTimeDuration, Float}; use oxsdatatypes::{DayTimeDuration, Float};
pub use spargebra::ParseError; pub use spargebra::ParseError;
@ -279,22 +279,22 @@ pub struct QueryExplanation {
impl QueryExplanation { impl QueryExplanation {
/// Writes the explanation as JSON. /// Writes the explanation as JSON.
pub fn write_in_json(&self, output: impl io::Write) -> io::Result<()> { pub fn write_in_json(&self, write: impl io::Write) -> io::Result<()> {
let mut writer = JsonWriter::from_writer(output); let mut writer = ToWriteJsonWriter::new(write);
writer.write_event(JsonEvent::StartObject)?; writer.write_event(JsonEvent::StartObject)?;
if let Some(parsing_duration) = self.parsing_duration { if let Some(parsing_duration) = self.parsing_duration {
writer.write_event(JsonEvent::ObjectKey("parsing duration in seconds"))?; writer.write_event(JsonEvent::ObjectKey("parsing duration in seconds".into()))?;
writer.write_event(JsonEvent::Number( writer.write_event(JsonEvent::Number(
&parsing_duration.as_seconds().to_string(), parsing_duration.as_seconds().to_string().into(),
))?; ))?;
} }
if let Some(planning_duration) = self.planning_duration { if let Some(planning_duration) = self.planning_duration {
writer.write_event(JsonEvent::ObjectKey("planning duration in seconds"))?; writer.write_event(JsonEvent::ObjectKey("planning duration in seconds".into()))?;
writer.write_event(JsonEvent::Number( writer.write_event(JsonEvent::Number(
&planning_duration.as_seconds().to_string(), planning_duration.as_seconds().to_string().into(),
))?; ))?;
} }
writer.write_event(JsonEvent::ObjectKey("plan"))?; writer.write_event(JsonEvent::ObjectKey("plan".into()))?;
self.inner.json_node(&mut writer, self.with_stats)?; self.inner.json_node(&mut writer, self.with_stats)?;
writer.write_event(JsonEvent::EndObject) writer.write_event(JsonEvent::EndObject)
} }

@ -5,7 +5,7 @@ from urllib.request import urlopen
TARGET_DEBIAN_VERSIONS = ["sid"] TARGET_DEBIAN_VERSIONS = ["sid"]
IGNORE_PACKAGES = {"oxigraph-js", "oxigraph-testsuite", "pyoxigraph", "sparql-smith"} IGNORE_PACKAGES = {"oxigraph-js", "oxigraph-testsuite", "pyoxigraph", "sparql-smith"}
ALLOWED_MISSING_PACKAGES = {"escargot", "oxhttp", "quick-xml"} ALLOWED_MISSING_PACKAGES = {"escargot", "json-event-parser", "oxhttp", "quick-xml"}
base_path = Path(__file__).parent.parent base_path = Path(__file__).parent.parent

Loading…
Cancel
Save