Migrates to failure from error_chain

pull/10/head
Tpt 6 years ago
parent f991fb2ccd
commit 12f80fc622
  1. 2
      lib/Cargo.toml
  2. 45
      lib/src/errors.rs
  3. 9
      lib/src/lib.rs
  4. 2
      lib/src/rio/ntriples/mod.rs
  5. 3
      lib/src/rio/turtle/mod.rs
  6. 16
      lib/src/rio/xml.rs
  7. 2
      lib/src/sparql/algebra.rs
  8. 3
      lib/src/sparql/parser.rs
  9. 7
      lib/src/sparql/plan.rs
  10. 72
      lib/src/sparql/xml_results.rs
  11. 20
      lib/src/store/encoded.rs
  12. 79
      lib/src/store/memory.rs
  13. 45
      lib/src/store/numeric_encoder.rs
  14. 24
      lib/src/store/rocksdb.rs
  15. 25
      lib/tests/rdf_test_cases.rs
  16. 36
      lib/tests/sparql_test_cases.rs
  17. 6
      python/src/lib.rs

@ -15,7 +15,6 @@ build = "build.rs"
travis-ci = { repository = "Tpt/rudf" } travis-ci = { repository = "Tpt/rudf" }
[dependencies] [dependencies]
error-chain = "0.12"
lazy_static = "1" lazy_static = "1"
rocksdb = "0.10" rocksdb = "0.10"
url = "1" url = "1"
@ -28,6 +27,7 @@ num-traits = "0.2"
rust_decimal = "0.10" rust_decimal = "0.10"
chrono = "0.4" chrono = "0.4"
language-tags = "0.2" language-tags = "0.2"
failure = "0.1"
[build-dependencies] [build-dependencies]
peg = "0.5" peg = "0.5"

@ -1,45 +0,0 @@
use quick_xml::Error as Xml_Error;
use std::fmt;
use std::sync::PoisonError;
error_chain! {
foreign_links {
Url(::url::ParseError);
RocksDB(::rocksdb::Error);
Utf8(::std::str::Utf8Error);
Io(::std::io::Error);
NTriples(::rio::ntriples::ParseError);
Turtle(::rio::turtle::ParseError);
SparqlParser(::sparql::parser::ParseError);
}
errors {
Xml(error: Xml_Error) {
description("XML parsing error")
display("XML parsing error: {:?}", error)
}
}
}
impl<T> From<PoisonError<T>> for Error {
fn from(_: PoisonError<T>) -> Self {
//TODO: improve conversion
"Unexpected lock error".into()
}
}
impl From<Xml_Error> for Error {
fn from(error: Xml_Error) -> Self {
match error {
Xml_Error::Io(error) => error.into(),
Xml_Error::Utf8(error) => error.into(),
error => ErrorKind::Xml(error).into(),
}
}
}
impl From<Error> for fmt::Error {
fn from(_: Error) -> Self {
fmt::Error
}
}

@ -33,8 +33,6 @@
extern crate byteorder; extern crate byteorder;
#[macro_use] #[macro_use]
extern crate error_chain;
#[macro_use]
extern crate lazy_static; extern crate lazy_static;
extern crate chrono; extern crate chrono;
extern crate language_tags; extern crate language_tags;
@ -45,13 +43,14 @@ extern crate rocksdb;
extern crate rust_decimal; extern crate rust_decimal;
extern crate url; extern crate url;
extern crate uuid; extern crate uuid;
#[macro_use]
extern crate failure;
mod errors;
pub mod model; pub mod model;
pub mod rio; pub mod rio;
pub mod sparql; pub mod sparql;
pub mod store; pub mod store;
mod utils; mod utils;
pub use errors::Error; pub use failure::Error;
pub use errors::Result; pub type Result<T> = ::std::result::Result<T, failure::Error>;

@ -41,8 +41,6 @@ use std::io::BufReader;
use std::io::Read; use std::io::Read;
use Result; use Result;
pub(crate) type ParseError = self::grammar::ParseError;
struct NTriplesIterator<R: Read> { struct NTriplesIterator<R: Read> {
buffer: String, buffer: String,
reader: BufReader<R>, reader: BufReader<R>,

@ -45,7 +45,7 @@ mod grammar {
pub fn read_turtle<'a, R: Read + 'a>( pub fn read_turtle<'a, R: Read + 'a>(
source: R, source: R,
base_uri: impl Into<Option<Url>>, base_uri: impl Into<Option<Url>>,
) -> super::super::super::errors::Result<impl Iterator<Item = Triple>> { ) -> super::super::super::Result<impl Iterator<Item = Triple>> {
let mut state = ParserState { let mut state = ParserState {
base_uri: base_uri.into(), base_uri: base_uri.into(),
namespaces: HashMap::default(), namespaces: HashMap::default(),
@ -78,5 +78,4 @@ mod grammar {
} }
} }
pub(crate) type ParseError = self::grammar::ParseError;
pub use self::grammar::read_turtle; pub use self::grammar::read_turtle;

@ -283,7 +283,11 @@ impl<R: BufRead> RdfXmlIterator<R> {
Some(RdfXmlState::ParseTypeCollectionPropertyElt { .. }) => { Some(RdfXmlState::ParseTypeCollectionPropertyElt { .. }) => {
RdfXmlNextProduction::NodeElt {} RdfXmlNextProduction::NodeElt {}
} }
None => return Err("No state in the stack: the XML is not balanced".into()), None => {
return Err(format_err!(
"No state in the stack: the XML is not balanced"
))
}
}; };
let new_state = match next_production { let new_state = match next_production {
@ -356,7 +360,9 @@ impl<R: BufRead> RdfXmlIterator<R> {
} }
} }
RdfXmlParseType::Literal => { RdfXmlParseType::Literal => {
return Err("rdf:parseType=\"Literal\" is not supported yet".into()); return Err(format_err!(
"rdf:parseType=\"Literal\" is not supported yet"
));
} }
RdfXmlParseType::Resource => self.build_parse_type_resource_property_elt( RdfXmlParseType::Resource => self.build_parse_type_resource_property_elt(
NamedNode::from(uri), NamedNode::from(uri),
@ -366,10 +372,12 @@ impl<R: BufRead> RdfXmlIterator<R> {
id_attr, id_attr,
), ),
RdfXmlParseType::Collection => { RdfXmlParseType::Collection => {
return Err("rdf:parseType=\"Collection\" is not supported yet".into()); return Err(format_err!(
"rdf:parseType=\"Collection\" is not supported yet"
));
} }
RdfXmlParseType::Other => { RdfXmlParseType::Other => {
return Err("Arbitrary rdf:parseType are not supported yet".into()); return Err(format_err!("Arbitrary rdf:parseType are not supported yet"));
} }
}, },
}; };

@ -30,7 +30,7 @@ impl Variable {
pub fn name(&self) -> Result<&str> { pub fn name(&self) -> Result<&str> {
match self { match self {
Variable::Variable { name } => Ok(name), Variable::Variable { name } => Ok(name),
_ => Err(format!("The variable {} has no name", self).into()), _ => Err(format_err!("The variable {} has no name", self)),
} }
} }
} }

@ -334,7 +334,7 @@ mod grammar {
pub fn read_sparql_query<'a, R: Read + 'a>( pub fn read_sparql_query<'a, R: Read + 'a>(
source: R, source: R,
base_uri: impl Into<Option<Url>>, base_uri: impl Into<Option<Url>>,
) -> super::super::super::errors::Result<Query> { ) -> super::super::super::Result<Query> {
let mut state = ParserState { let mut state = ParserState {
base_uri: base_uri.into(), base_uri: base_uri.into(),
namespaces: HashMap::default(), namespaces: HashMap::default(),
@ -352,5 +352,4 @@ mod grammar {
} }
} }
pub(crate) type ParseError = self::grammar::ParseError;
pub use self::grammar::read_sparql_query; pub use self::grammar::read_sparql_query;

@ -629,7 +629,7 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
} else if *name == *xsd::STRING { } else if *name == *xsd::STRING {
self.build_cast(parameters, PlanExpression::StringCast, variables, "string")? self.build_cast(parameters, PlanExpression::StringCast, variables, "string")?
} else { } else {
Err(format!("Not supported custom function {}", expression))? Err(format_err!("Not supported custom function {}", expression))?
}, },
_ => unimplemented!(), _ => unimplemented!(),
}) })
@ -647,7 +647,10 @@ impl<'a, S: EncodedQuadsStore> PlanBuilder<'a, S> {
self.build_for_expression(&parameters[0], variables)?, self.build_for_expression(&parameters[0], variables)?,
))) )))
} else { } else {
Err(format!("The xsd:{} casting takes only one parameter", name).into()) Err(format_err!(
"The xsd:{} casting takes only one parameter",
name
))
} }
} }

@ -33,10 +33,10 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
let (ns, event) = reader.read_namespaced_event(&mut buffer, &mut namespace_buffer)?; let (ns, event) = reader.read_namespaced_event(&mut buffer, &mut namespace_buffer)?;
if let Some(ns) = ns { if let Some(ns) = ns {
if ns != b"http://www.w3.org/2005/sparql-results#".as_ref() { if ns != b"http://www.w3.org/2005/sparql-results#".as_ref() {
return Err(format!( return Err(format_err!(
"Unexpected namespace found in RDF/XML query result: {}", "Unexpected namespace found in RDF/XML query result: {}",
reader.decode(ns) reader.decode(ns)
).into()); ));
} }
} }
event event
@ -47,21 +47,21 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
if event.name() == b"sparql" { if event.name() == b"sparql" {
state = State::Sparql; state = State::Sparql;
} else { } else {
return Err(format!("Expecting <sparql> tag, found {}", reader.decode(event.name())).into()); return Err(format_err!("Expecting <sparql> tag, found {}", reader.decode(event.name())));
} }
} }
State::Sparql => { State::Sparql => {
if event.name() == b"head" { if event.name() == b"head" {
state = State::Head; state = State::Head;
} else { } else {
return Err(format!("Expecting <head> tag, found {}", reader.decode(event.name())).into()); return Err(format_err!("Expecting <head> tag, found {}", reader.decode(event.name())));
} }
} }
State::Head => if event.name() == b"variable" || event.name() == b"link" { State::Head => if event.name() == b"variable" || event.name() == b"link" {
return Err("<variable> and <link> tag should be autoclosing".into()); return Err(format_err!("<variable> and <link> tag should be autoclosing"));
} else { } else {
return Err(format!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())).into()); return Err(format_err!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())));
}, }
State::AfterHead => { State::AfterHead => {
if event.name() == b"boolean" { if event.name() == b"boolean" {
state = State::Boolean state = State::Boolean
@ -81,10 +81,10 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
}), }),
))); )));
} else if event.name() != b"link" && event.name() != b"results" && event.name() != b"boolean" { } else if event.name() != b"link" && event.name() != b"results" && event.name() != b"boolean" {
return Err(format!("Expecting sparql tag, found {}", reader.decode(event.name())).into()); return Err(format_err!("Expecting sparql tag, found {}", reader.decode(event.name())));
} }
} }
State::Boolean => return Err(format!("Unexpected tag inside of <boolean> tag: {}", reader.decode(event.name())).into()) State::Boolean => return Err(format_err!("Unexpected tag inside of <boolean> tag: {}", reader.decode(event.name())))
}, },
Event::Empty(event) => match state { Event::Empty(event) => match state {
State::Head => { State::Head => {
@ -92,12 +92,12 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
let name = event.attributes() let name = event.attributes()
.filter_map(|attr| attr.ok()) .filter_map(|attr| attr.ok())
.find(|attr| attr.key == b"name") .find(|attr| attr.key == b"name")
.ok_or("No name attribute found for the <variable> tag"); .ok_or(format_err!("No name attribute found for the <variable> tag"));
variables.push(name?.unescape_and_decode_value(&reader)?); variables.push(name?.unescape_and_decode_value(&reader)?);
} else if event.name() == b"link" { } else if event.name() == b"link" {
// no op // no op
} else { } else {
return Err(format!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())).into()); return Err(format_err!("Expecting <variable> or <link> tag, found {}", reader.decode(event.name())));
} }
}, },
State::AfterHead => { State::AfterHead => {
@ -107,10 +107,10 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
Box::new(empty()), Box::new(empty()),
))) )))
} else { } else {
return Err(format!("Unexpected autoclosing tag <{}>", reader.decode(event.name())).into()) return Err(format_err!("Unexpected autoclosing tag <{}>", reader.decode(event.name())))
} }
} }
_ => return Err(format!("Unexpected autoclosing tag <{}>", reader.decode(event.name())).into()) _ => return Err(format_err!("Unexpected autoclosing tag <{}>", reader.decode(event.name())))
}, },
Event::Text(event) => { Event::Text(event) => {
let value = event.unescaped()?; let value = event.unescaped()?;
@ -121,18 +121,18 @@ pub fn read_xml_results(source: impl BufRead + 'static) -> Result<QueryResult<'s
} else if value.as_ref() == b"false" { } else if value.as_ref() == b"false" {
Ok(QueryResult::Boolean(false)) Ok(QueryResult::Boolean(false))
} else { } else {
Err(format!("Unexpected boolean value. Found {}", reader.decode(&value)).into()) Err(format_err!("Unexpected boolean value. Found {}", reader.decode(&value)))
}; };
} }
_ => Err(format!("Unexpected textual value found: {}", reader.decode(&value)).into()) _ => Err(format_err!("Unexpected textual value found: {}", reader.decode(&value)))
}; };
}, },
Event::End(_) => if let State::Head = state { Event::End(_) => if let State::Head = state {
state = State::AfterHead; state = State::AfterHead;
} else { } else {
return Err("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag".into()); return Err(format_err!("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag"));
}, },
Event::Eof => return Err("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag".into()), Event::Eof => return Err(format_err!("Unexpected early file end. All results file should have a <head> and a <result> or <boolean> tag")),
_ => (), _ => (),
} }
} }
@ -178,10 +178,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
}; };
if let Some(ns) = ns { if let Some(ns) = ns {
if ns != b"http://www.w3.org/2005/sparql-results#".as_ref() { if ns != b"http://www.w3.org/2005/sparql-results#".as_ref() {
return Some(Err(format!( return Some(Err(format_err!(
"Unexpected namespace found in RDF/XML query result: {}", "Unexpected namespace found in RDF/XML query result: {}",
self.reader.decode(ns) self.reader.decode(ns)
).into())); )));
} }
} }
match event { match event {
@ -189,10 +189,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
State::Start => if event.name() == b"result" { State::Start => if event.name() == b"result" {
state = State::Result; state = State::Result;
} else { } else {
return Some(Err(format!( return Some(Err(format_err!(
"Expecting <result>, found {}", "Expecting <result>, found {}",
self.reader.decode(event.name()) self.reader.decode(event.name())
).into())); )));
}, },
State::Result => if event.name() == b"binding" { State::Result => if event.name() == b"binding" {
match event match event
@ -205,23 +205,23 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
Err(error) => return Some(Err(error.into())), Err(error) => return Some(Err(error.into())),
}, },
None => { None => {
return Some(Err( return Some(Err(format_err!(
"No name attribute found for the <binding> tag".into() "No name attribute found for the <binding> tag"
)) )))
} }
} }
state = State::Binding; state = State::Binding;
} else { } else {
return Some(Err(format!( return Some(Err(format_err!(
"Expecting <binding>, found {}", "Expecting <binding>, found {}",
self.reader.decode(event.name()) self.reader.decode(event.name())
).into())); )));
}, },
State::Binding => { State::Binding => {
if term.is_some() { if term.is_some() {
return Some(Err( return Some(Err(format_err!(
"There is already a value for the current binding".into() "There is already a value for the current binding"
)); )));
} }
if event.name() == b"uri" { if event.name() == b"uri" {
state = State::Uri; state = State::Uri;
@ -251,10 +251,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
} }
state = State::Literal; state = State::Literal;
} else { } else {
return Some(Err(format!( return Some(Err(format_err!(
"Expecting <uri>, <bnode> or <literal> found {}", "Expecting <uri>, <bnode> or <literal> found {}",
self.reader.decode(event.name()) self.reader.decode(event.name())
).into())); )));
} }
} }
_ => (), _ => (),
@ -279,10 +279,10 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
term = Some(build_literal(value, &lang, &datatype).into()); term = Some(build_literal(value, &lang, &datatype).into());
} }
_ => { _ => {
return Some(Err(format!( return Some(Err(format_err!(
"Unexpected textual value found: {}", "Unexpected textual value found: {}",
self.reader.decode(&data) self.reader.decode(&data)
).into())) )))
} }
}, },
Err(error) => return Some(Err(error.into())), Err(error) => return Some(Err(error.into())),
@ -296,12 +296,12 @@ impl<R: BufRead> Iterator for ResultsIterator<R> {
new_bindings[self.mapping[var]] = Some(term.clone()) new_bindings[self.mapping[var]] = Some(term.clone())
} }
(Some(var), None) => { (Some(var), None) => {
return Some(Err(format!( return Some(Err(format_err!(
"No variable found for variable {}", "No variable found for variable {}",
self.reader.decode(&var) self.reader.decode(&var)
).into())) )))
} }
_ => return Some(Err("No name found for <binding> tag".into())), _ => return Some(Err(format_err!("No name found for <binding> tag"))),
} }
term = None; term = None;
state = State::Result; state = State::Result;

@ -353,8 +353,8 @@ impl<S: EncodedQuadsStore> Dataset for StoreDataset<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreDataset<S> { impl<S: EncodedQuadsStore> fmt::Display for StoreDataset<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for quad in self.iter()? { for quad in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", quad?)?; writeln!(fmt, "{}", quad.map_err(|_| fmt::Error)?)?;
} }
Ok(()) Ok(())
} }
@ -539,8 +539,8 @@ impl<S: EncodedQuadsStore> NamedGraph for StoreNamedGraph<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreNamedGraph<S> { impl<S: EncodedQuadsStore> fmt::Display for StoreNamedGraph<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for triple in self.iter()? { for triple in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", triple?)?; writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?;
} }
Ok(()) Ok(())
} }
@ -694,8 +694,8 @@ impl<S: EncodedQuadsStore> Graph for StoreDefaultGraph<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreDefaultGraph<S> { impl<S: EncodedQuadsStore> fmt::Display for StoreDefaultGraph<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for triple in self.iter()? { for triple in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", triple?)?; writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?;
} }
Ok(()) Ok(())
} }
@ -840,11 +840,11 @@ impl<S: EncodedQuadsStore> Graph for StoreUnionGraph<S> {
} }
fn insert(&self, _triple: &Triple) -> Result<()> { fn insert(&self, _triple: &Triple) -> Result<()> {
Err("Union graph is not writable".into()) Err(format_err!("Union graph is not writable"))
} }
fn remove(&self, _triple: &Triple) -> Result<()> { fn remove(&self, _triple: &Triple) -> Result<()> {
Err("Union graph is not writable".into()) Err(format_err!("Union graph is not writable"))
} }
fn len(&self) -> Result<usize> { fn len(&self) -> Result<usize> {
@ -858,8 +858,8 @@ impl<S: EncodedQuadsStore> Graph for StoreUnionGraph<S> {
impl<S: EncodedQuadsStore> fmt::Display for StoreUnionGraph<S> { impl<S: EncodedQuadsStore> fmt::Display for StoreUnionGraph<S> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
for triple in self.iter()? { for triple in self.iter().map_err(|_| fmt::Error)? {
writeln!(fmt, "{}", triple?)?; writeln!(fmt, "{}", triple.map_err(|_| fmt::Error)?)?;
} }
Ok(()) Ok(())
} }

@ -1,6 +1,10 @@
use failure::Backtrace;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::sync::PoisonError;
use std::sync::RwLock; use std::sync::RwLock;
use std::sync::RwLockReadGuard;
use std::sync::RwLockWriteGuard;
use store::encoded::*; use store::encoded::*;
use store::numeric_encoder::*; use store::numeric_encoder::*;
use Result; use Result;
@ -71,8 +75,8 @@ impl BytesStore for MemoryStore {
type BytesOutput = Vec<u8>; type BytesOutput = Vec<u8>;
fn insert_bytes(&self, value: &[u8]) -> Result<u64> { fn insert_bytes(&self, value: &[u8]) -> Result<u64> {
let mut id2str = self.id2str.write()?; let mut id2str = self.id2str.write().map_err(MemoryStorePoisonError::from)?;
let mut str2id = self.str2id.write()?; let mut str2id = self.str2id.write().map_err(MemoryStorePoisonError::from)?;
let id = str2id.entry(value.to_vec()).or_insert_with(|| { let id = str2id.entry(value.to_vec()).or_insert_with(|| {
let id = id2str.len() as u64; let id = id2str.len() as u64;
id2str.push(value.to_vec()); id2str.push(value.to_vec());
@ -83,7 +87,7 @@ impl BytesStore for MemoryStore {
fn get_bytes(&self, id: u64) -> Result<Option<Vec<u8>>> { fn get_bytes(&self, id: u64) -> Result<Option<Vec<u8>>> {
//TODO: use try_from when stable //TODO: use try_from when stable
let id2str = self.id2str.read()?; let id2str = self.id2str.read().map_err(MemoryStorePoisonError::from)?;
Ok(if id2str.len() as u64 <= id { Ok(if id2str.len() as u64 <= id {
None None
} else { } else {
@ -114,7 +118,7 @@ impl EncodedQuadsStore for MemoryStore {
fn quads(&self) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { fn quads(&self) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
for (s, pos) in &graph.spo { for (s, pos) in &graph.spo {
for (p, os) in pos.iter() { for (p, os) in pos.iter() {
for o in os.iter() { for o in os.iter() {
@ -131,7 +135,7 @@ impl EncodedQuadsStore for MemoryStore {
subject: EncodedTerm, subject: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(pos) = graph.spo.get(&subject) { if let Some(pos) = graph.spo.get(&subject) {
for (p, os) in pos.iter() { for (p, os) in pos.iter() {
for o in os.iter() { for o in os.iter() {
@ -149,7 +153,7 @@ impl EncodedQuadsStore for MemoryStore {
predicate: EncodedTerm, predicate: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(pos) = graph.spo.get(&subject) { if let Some(pos) = graph.spo.get(&subject) {
if let Some(os) = pos.get(&predicate) { if let Some(os) = pos.get(&predicate) {
for o in os.iter() { for o in os.iter() {
@ -168,7 +172,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm, object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(pos) = graph.spo.get(&subject) { if let Some(pos) = graph.spo.get(&subject) {
if let Some(os) = pos.get(&predicate) { if let Some(os) = pos.get(&predicate) {
if os.contains(&object) { if os.contains(&object) {
@ -191,7 +195,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm, object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(sps) = graph.osp.get(&object) { if let Some(sps) = graph.osp.get(&object) {
if let Some(ps) = sps.get(&subject) { if let Some(ps) = sps.get(&subject) {
for p in ps.iter() { for p in ps.iter() {
@ -208,7 +212,7 @@ impl EncodedQuadsStore for MemoryStore {
predicate: EncodedTerm, predicate: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(oss) = graph.pos.get(&predicate) { if let Some(oss) = graph.pos.get(&predicate) {
for (o, ss) in oss.iter() { for (o, ss) in oss.iter() {
for s in ss.iter() { for s in ss.iter() {
@ -226,7 +230,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm, object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(oss) = graph.pos.get(&predicate) { if let Some(oss) = graph.pos.get(&predicate) {
if let Some(ss) = oss.get(&object) { if let Some(ss) = oss.get(&object) {
for s in ss.iter() { for s in ss.iter() {
@ -243,7 +247,7 @@ impl EncodedQuadsStore for MemoryStore {
object: EncodedTerm, object: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
for (graph_name, graph) in self.graph_indexes.read()?.iter() { for (graph_name, graph) in self.graph_indexes()?.iter() {
if let Some(sps) = graph.osp.get(&object) { if let Some(sps) = graph.osp.get(&object) {
for (s, ps) in sps.iter() { for (s, ps) in sps.iter() {
for p in ps.iter() { for p in ps.iter() {
@ -260,7 +264,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) { if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
for (s, pos) in &graph.spo { for (s, pos) in &graph.spo {
for (p, os) in pos.iter() { for (p, os) in pos.iter() {
for o in os.iter() { for o in os.iter() {
@ -278,7 +282,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) { if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(pos) = graph.spo.get(&subject) { if let Some(pos) = graph.spo.get(&subject) {
for (p, os) in pos.iter() { for (p, os) in pos.iter() {
for o in os.iter() { for o in os.iter() {
@ -297,7 +301,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) { if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(pos) = graph.spo.get(&subject) { if let Some(pos) = graph.spo.get(&subject) {
if let Some(os) = pos.get(&predicate) { if let Some(os) = pos.get(&predicate) {
for o in os.iter() { for o in os.iter() {
@ -316,7 +320,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) { if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(sps) = graph.osp.get(&object) { if let Some(sps) = graph.osp.get(&object) {
if let Some(ps) = sps.get(&subject) { if let Some(ps) = sps.get(&subject) {
for p in ps.iter() { for p in ps.iter() {
@ -334,7 +338,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) { if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(oss) = graph.pos.get(&predicate) { if let Some(oss) = graph.pos.get(&predicate) {
for (o, ss) in oss.iter() { for (o, ss) in oss.iter() {
for s in ss.iter() { for s in ss.iter() {
@ -353,7 +357,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) { if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(oss) = graph.pos.get(&predicate) { if let Some(oss) = graph.pos.get(&predicate) {
if let Some(ss) = oss.get(&object) { if let Some(ss) = oss.get(&object) {
for s in ss.iter() { for s in ss.iter() {
@ -371,7 +375,7 @@ impl EncodedQuadsStore for MemoryStore {
graph_name: EncodedTerm, graph_name: EncodedTerm,
) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> { ) -> Result<<Vec<Result<EncodedQuad>> as IntoIterator>::IntoIter> {
let mut result = Vec::default(); let mut result = Vec::default();
if let Some(graph) = self.graph_indexes.read()?.get(&graph_name) { if let Some(graph) = self.graph_indexes()?.get(&graph_name) {
if let Some(sps) = graph.osp.get(&object) { if let Some(sps) = graph.osp.get(&object) {
for (s, ps) in sps.iter() { for (s, ps) in sps.iter() {
for p in ps.iter() { for p in ps.iter() {
@ -385,8 +389,7 @@ impl EncodedQuadsStore for MemoryStore {
fn contains(&self, quad: &EncodedQuad) -> Result<bool> { fn contains(&self, quad: &EncodedQuad) -> Result<bool> {
Ok(self Ok(self
.graph_indexes .graph_indexes()?
.read()?
.get(&quad.graph_name) .get(&quad.graph_name)
.map_or(false, |graph| { .map_or(false, |graph| {
graph.spo.get(&quad.subject).map_or(false, |po| { graph.spo.get(&quad.subject).map_or(false, |po| {
@ -397,7 +400,7 @@ impl EncodedQuadsStore for MemoryStore {
} }
fn insert(&self, quad: &EncodedQuad) -> Result<()> { fn insert(&self, quad: &EncodedQuad) -> Result<()> {
let mut graph_indexes = self.graph_indexes.write()?; let mut graph_indexes = self.graph_indexes_mut()?;
let graph = graph_indexes let graph = graph_indexes
.entry(quad.graph_name) .entry(quad.graph_name)
.or_insert_with(MemoryGraphIndexes::default); .or_insert_with(MemoryGraphIndexes::default);
@ -426,7 +429,7 @@ impl EncodedQuadsStore for MemoryStore {
} }
fn remove(&self, quad: &EncodedQuad) -> Result<()> { fn remove(&self, quad: &EncodedQuad) -> Result<()> {
let mut graph_indexes = self.graph_indexes.write()?; let mut graph_indexes = self.graph_indexes_mut()?;
let mut empty_graph = false; let mut empty_graph = false;
if let Some(graph) = graph_indexes.get_mut(&quad.graph_name) { if let Some(graph) = graph_indexes.get_mut(&quad.graph_name) {
{ {
@ -491,3 +494,35 @@ impl EncodedQuadsStore for MemoryStore {
Ok(()) Ok(())
} }
} }
impl MemoryStore {
fn graph_indexes(&self) -> Result<RwLockReadGuard<BTreeMap<EncodedTerm, MemoryGraphIndexes>>> {
Ok(self
.graph_indexes
.read()
.map_err(MemoryStorePoisonError::from)?)
}
fn graph_indexes_mut(
&self,
) -> Result<RwLockWriteGuard<BTreeMap<EncodedTerm, MemoryGraphIndexes>>> {
Ok(self
.graph_indexes
.write()
.map_err(MemoryStorePoisonError::from)?)
}
}
#[derive(Debug, Fail)]
#[fail(display = "MemoryStore Mutex was poisoned")]
pub struct MemoryStorePoisonError {
backtrace: Backtrace,
}
impl<T> From<PoisonError<T>> for MemoryStorePoisonError {
fn from(_: PoisonError<T>) -> Self {
Self {
backtrace: Backtrace::new(),
}
}
}

@ -14,7 +14,6 @@ use std::str;
use std::str::FromStr; use std::str::FromStr;
use url::Url; use url::Url;
use uuid::Uuid; use uuid::Uuid;
use Error;
use Result; use Result;
const EMPTY_STRING_ID: u64 = 0; const EMPTY_STRING_ID: u64 = 0;
@ -47,7 +46,9 @@ pub trait BytesStore {
{ {
Ok(()) Ok(())
} else { } else {
Err("Failed to properly setup the basic string ids in the dictionnary".into()) Err(format_err!(
"Failed to properly setup the basic string ids in the dictionnary"
))
} }
} }
} }
@ -317,17 +318,17 @@ impl<R: Read> TermReader for R {
NaiveDateTime::from_timestamp_opt( NaiveDateTime::from_timestamp_opt(
self.read_i64::<LittleEndian>()?, self.read_i64::<LittleEndian>()?,
self.read_u32::<LittleEndian>()?, self.read_u32::<LittleEndian>()?,
).ok_or("Invalid date time serialization")?, ).ok_or_else(|| format_err!("Invalid date time serialization"))?,
FixedOffset::east_opt(self.read_i32::<LittleEndian>()?) FixedOffset::east_opt(self.read_i32::<LittleEndian>()?)
.ok_or("Invalid timezone offset")?, .ok_or_else(|| format_err!("Invalid timezone offset"))?,
))), ))),
TYPE_NAIVE_DATE_TIME_LITERAL => Ok(EncodedTerm::NaiveDateTime( TYPE_NAIVE_DATE_TIME_LITERAL => Ok(EncodedTerm::NaiveDateTime(
NaiveDateTime::from_timestamp_opt( NaiveDateTime::from_timestamp_opt(
self.read_i64::<LittleEndian>()?, self.read_i64::<LittleEndian>()?,
self.read_u32::<LittleEndian>()?, self.read_u32::<LittleEndian>()?,
).ok_or("Invalid date time serialization")?, ).ok_or_else(|| format_err!("Invalid date time serialization"))?,
)), )),
_ => Err("the term buffer has an invalid type id".into()), _ => Err(format_err!("the term buffer has an invalid type id")),
} }
} }
@ -483,37 +484,37 @@ impl<S: BytesStore> Encoder<S> {
} else if literal.is_boolean() { } else if literal.is_boolean() {
literal literal
.to_bool() .to_bool()
.ok_or_else(|| Error::from("boolean literal without boolean value"))? .ok_or_else(|| format_err!("boolean literal without boolean value"))?
.into() .into()
} else if literal.is_float() { } else if literal.is_float() {
literal literal
.to_float() .to_float()
.ok_or_else(|| Error::from("float literal without float value"))? .ok_or_else(|| format_err!("float literal without float value"))?
.into() .into()
} else if literal.is_double() { } else if literal.is_double() {
literal literal
.to_double() .to_double()
.ok_or_else(|| Error::from("double literal without double value"))? .ok_or_else(|| format_err!("double literal without double value"))?
.into() .into()
} else if literal.is_integer() { } else if literal.is_integer() {
literal literal
.to_integer() .to_integer()
.ok_or_else(|| Error::from("integer literal without integer value"))? .ok_or_else(|| format_err!("integer literal without integer value"))?
.into() .into()
} else if literal.is_decimal() { } else if literal.is_decimal() {
literal literal
.to_decimal() .to_decimal()
.ok_or_else(|| Error::from("decimal literal without decimal value"))? .ok_or_else(|| format_err!("decimal literal without decimal value"))?
.into() .into()
} else if literal.is_date_time_stamp() { } else if literal.is_date_time_stamp() {
literal literal
.to_date_time_stamp() .to_date_time_stamp()
.ok_or_else(|| Error::from("dateTimeStamp literal without dateTimeStamp value"))? .ok_or_else(|| format_err!("dateTimeStamp literal without dateTimeStamp value"))?
.into() .into()
} else if literal.is_decimal() { } else if literal.is_decimal() {
literal literal
.to_date_time() .to_date_time()
.ok_or_else(|| Error::from("dateTime literal without dateTime value"))? .ok_or_else(|| format_err!("dateTime literal without dateTime value"))?
.into() .into()
} else { } else {
EncodedTerm::TypedLiteral { EncodedTerm::TypedLiteral {
@ -565,7 +566,9 @@ impl<S: BytesStore> Encoder<S> {
pub fn decode_term(&self, encoded: EncodedTerm) -> Result<Term> { pub fn decode_term(&self, encoded: EncodedTerm) -> Result<Term> {
match encoded { match encoded {
EncodedTerm::DefaultGraph {} => Err("The default graph tag is not a valid term".into()), EncodedTerm::DefaultGraph {} => {
Err(format_err!("The default graph tag is not a valid term"))
}
EncodedTerm::NamedNode { iri_id } => { EncodedTerm::NamedNode { iri_id } => {
Ok(NamedNode::from(self.decode_url_value(iri_id)?).into()) Ok(NamedNode::from(self.decode_url_value(iri_id)?).into())
} }
@ -604,15 +607,21 @@ impl<S: BytesStore> Encoder<S> {
match self.decode_term(encoded)? { match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node.into()), Term::NamedNode(named_node) => Ok(named_node.into()),
Term::BlankNode(blank_node) => Ok(blank_node.into()), Term::BlankNode(blank_node) => Ok(blank_node.into()),
Term::Literal(_) => Err("A literal has ben found instead of a named node".into()), Term::Literal(_) => Err(format_err!(
"A literal has ben found instead of a named node"
)),
} }
} }
pub fn decode_named_node(&self, encoded: EncodedTerm) -> Result<NamedNode> { pub fn decode_named_node(&self, encoded: EncodedTerm) -> Result<NamedNode> {
match self.decode_term(encoded)? { match self.decode_term(encoded)? {
Term::NamedNode(named_node) => Ok(named_node), Term::NamedNode(named_node) => Ok(named_node),
Term::BlankNode(_) => Err("A blank node has been found instead of a named node".into()), Term::BlankNode(_) => Err(format_err!(
Term::Literal(_) => Err("A literal has ben found instead of a named node".into()), "A blank node has been found instead of a named node"
)),
Term::Literal(_) => Err(format_err!(
"A literal has ben found instead of a named node"
)),
} }
} }
@ -653,7 +662,7 @@ impl<S: BytesStore> Encoder<S> {
fn decode_value(&self, id: u64) -> Result<S::BytesOutput> { fn decode_value(&self, id: u64) -> Result<S::BytesOutput> {
self.string_store self.string_store
.get_bytes(id)? .get_bytes(id)?
.ok_or_else(|| "value not found in the dictionary".into()) .ok_or_else(|| format_err!("value not found in the dictionary"))
} }
} }

@ -1,5 +1,6 @@
use byteorder::ByteOrder; use byteorder::ByteOrder;
use byteorder::LittleEndian; use byteorder::LittleEndian;
use failure::Backtrace;
use rocksdb::ColumnFamily; use rocksdb::ColumnFamily;
use rocksdb::DBRawIterator; use rocksdb::DBRawIterator;
use rocksdb::DBVector; use rocksdb::DBVector;
@ -10,6 +11,7 @@ use std::io::Cursor;
use std::path::Path; use std::path::Path;
use std::str; use std::str;
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::PoisonError;
use store::encoded::EncodedQuadsStore; use store::encoded::EncodedQuadsStore;
use store::encoded::StoreDataset; use store::encoded::StoreDataset;
use store::numeric_encoder::*; use store::numeric_encoder::*;
@ -86,7 +88,11 @@ impl BytesStore for RocksDbStore {
Ok(if let Some(id) = self.db.get_cf(self.str2id_cf, value)? { Ok(if let Some(id) = self.db.get_cf(self.str2id_cf, value)? {
LittleEndian::read_u64(&id) LittleEndian::read_u64(&id)
} else { } else {
let id = self.str_id_counter.lock()?.get_and_increment(&self.db)? as u64; let id = self
.str_id_counter
.lock()
.map_err(RocksDBCounterMutexPoisonError::from)?
.get_and_increment(&self.db)? as u64;
let id_bytes = to_bytes(id); let id_bytes = to_bytes(id);
let mut batch = WriteBatch::default(); let mut batch = WriteBatch::default();
batch.put_cf(self.id2str_cf, &id_bytes, value)?; batch.put_cf(self.id2str_cf, &id_bytes, value)?;
@ -326,7 +332,7 @@ impl EncodedQuadsStore for RocksDbStore {
pub fn get_cf(db: &DB, name: &str) -> Result<ColumnFamily> { pub fn get_cf(db: &DB, name: &str) -> Result<ColumnFamily> {
db.cf_handle(name) db.cf_handle(name)
.ok_or_else(|| "column family not found".into()) .ok_or_else(|| format_err!("column family not found"))
} }
struct RocksDBCounter { struct RocksDBCounter {
@ -516,3 +522,17 @@ fn to_bytes(int: u64) -> [u8; 8] {
LittleEndian::write_u64(&mut buf, int); LittleEndian::write_u64(&mut buf, int);
buf buf
} }
#[derive(Debug, Fail)]
#[fail(display = "RocksDBStore Mutex was poisoned")]
pub struct RocksDBCounterMutexPoisonError {
backtrace: Backtrace,
}
impl<T> From<PoisonError<T>> for RocksDBCounterMutexPoisonError {
fn from(_: PoisonError<T>) -> Self {
Self {
backtrace: Backtrace::new(),
}
}
}

@ -5,6 +5,8 @@ extern crate lazy_static;
extern crate reqwest; extern crate reqwest;
extern crate rudf; extern crate rudf;
extern crate url; extern crate url;
#[macro_use]
extern crate failure;
use reqwest::Client; use reqwest::Client;
use reqwest::Response; use reqwest::Response;
@ -212,7 +214,7 @@ impl RDFClient {
{ {
self.get(url) self.get(url)
} else { } else {
Err(format!("HTTP request error: {}", error.description()).into()) Err(format_err!("HTTP request error: {}", error.description()))
}, },
} }
} }
@ -296,9 +298,9 @@ impl<'a> Iterator for TestManifest<'a> {
{ {
Some(Term::NamedNode(c)) => match c.as_str().split("#").last() { Some(Term::NamedNode(c)) => match c.as_str().split("#").last() {
Some(k) => k.to_string(), Some(k) => k.to_string(),
None => return Some(Err("no type".into())), None => return Some(Err(format_err!("no type"))),
}, },
_ => return Some(Err("no type".into())), _ => return Some(Err(format_err!("no type"))),
}; };
let name = match self let name = match self
.graph .graph
@ -322,8 +324,8 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap() .unwrap()
{ {
Some(Term::NamedNode(n)) => n.as_url().clone(), Some(Term::NamedNode(n)) => n.as_url().clone(),
Some(_) => return Some(Err("invalid action".into())), Some(_) => return Some(Err(format_err!("invalid action"))),
None => return Some(Err("action not found".into())), None => return Some(Err(format_err!("action not found"))),
}; };
let result = match self let result = match self
.graph .graph
@ -331,7 +333,7 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap() .unwrap()
{ {
Some(Term::NamedNode(n)) => Some(n.as_url().clone()), Some(Term::NamedNode(n)) => Some(n.as_url().clone()),
Some(_) => return Some(Err("invalid result".into())), Some(_) => return Some(Err(format_err!("invalid result"))),
None => None, None => None,
}; };
Some(Ok(Test { Some(Ok(Test {
@ -343,7 +345,7 @@ impl<'a> Iterator for TestManifest<'a> {
result, result,
})) }))
} }
Some(_) => Some(Err("invalid test list".into())), Some(_) => Some(Err(format_err!("invalid test list"))),
None => { None => {
match self.manifests_to_do.pop() { match self.manifests_to_do.pop() {
Some(url) => { Some(url) => {
@ -371,7 +373,7 @@ impl<'a> Iterator for TestManifest<'a> {
}), }),
); );
} }
Some(_) => return Some(Err("invalid tests list".into())), Some(_) => return Some(Err(format_err!("invalid tests list"))),
None => (), None => (),
} }
@ -388,9 +390,10 @@ impl<'a> Iterator for TestManifest<'a> {
)); ));
} }
Some(term) => { Some(term) => {
return Some(Err( return Some(Err(format_err!(
format!("Invalid tests list. Got term {}", term).into() "Invalid tests list. Got term {}",
)) term
)))
} }
None => (), None => (),
} }

@ -4,6 +4,8 @@ extern crate lazy_static;
extern crate reqwest; extern crate reqwest;
extern crate rudf; extern crate rudf;
extern crate url; extern crate url;
#[macro_use]
extern crate failure;
use reqwest::Client; use reqwest::Client;
use reqwest::Response; use reqwest::Response;
@ -276,7 +278,7 @@ impl RDFClient {
} else if url.as_str().ends_with(".rdf") { } else if url.as_str().ends_with(".rdf") {
read_rdf_xml(BufReader::new(self.get(&url)?), Some(url)).collect() read_rdf_xml(BufReader::new(self.get(&url)?), Some(url)).collect()
} else { } else {
Err(format!("Serialization type not found for {}", url).into()) Err(format_err!("Serialization type not found for {}", url))
} }
} }
@ -299,7 +301,7 @@ impl RDFClient {
{ {
self.get(url) self.get(url)
} else { } else {
Err(format!("HTTP request error: {}", error.description()).into()) Err(format_err!("HTTP request error: {}", error.description()))
}, },
} }
} }
@ -518,9 +520,9 @@ impl<'a> Iterator for TestManifest<'a> {
{ {
Some(Term::NamedNode(c)) => match c.as_str().split("#").last() { Some(Term::NamedNode(c)) => match c.as_str().split("#").last() {
Some(k) => k.to_string(), Some(k) => k.to_string(),
None => return Some(Err("no type".into())), None => return Some(Err(format_err!("no type"))),
}, },
_ => return Some(Err("no type".into())), _ => return Some(Err(format_err!("no type"))),
}; };
let name = match self let name = match self
.graph .graph
@ -552,8 +554,8 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap() .unwrap()
{ {
Some(Term::NamedNode(q)) => q.into(), Some(Term::NamedNode(q)) => q.into(),
Some(_) => return Some(Err("invalid query".into())), Some(_) => return Some(Err(format_err!("invalid query"))),
None => return Some(Err("query not found".into())), None => return Some(Err(format_err!("query not found"))),
}; };
let data = match self let data = match self
.graph .graph
@ -573,11 +575,12 @@ impl<'a> Iterator for TestManifest<'a> {
}).collect(); }).collect();
(query, data, graph_data) (query, data, graph_data)
} }
Some(_) => return Some(Err("invalid action".into())), Some(_) => return Some(Err(format_err!("invalid action"))),
None => { None => {
return Some(Err( return Some(Err(format_err!(
format!("action not found for test {}", test_subject).into() "action not found for test {}",
)) test_subject
)))
} }
}; };
let result = match self let result = match self
@ -586,7 +589,7 @@ impl<'a> Iterator for TestManifest<'a> {
.unwrap() .unwrap()
{ {
Some(Term::NamedNode(n)) => Some(n.into()), Some(Term::NamedNode(n)) => Some(n.into()),
Some(_) => return Some(Err("invalid result".into())), Some(_) => return Some(Err(format_err!("invalid result"))),
None => None, None => None,
}; };
Some(Ok(Test { Some(Ok(Test {
@ -600,7 +603,7 @@ impl<'a> Iterator for TestManifest<'a> {
result, result,
})) }))
} }
Some(_) => Some(Err("invalid test list".into())), Some(_) => Some(Err(format_err!("invalid test list"))),
None => { None => {
match self.manifests_to_do.pop() { match self.manifests_to_do.pop() {
Some(url) => { Some(url) => {
@ -628,7 +631,7 @@ impl<'a> Iterator for TestManifest<'a> {
}), }),
); );
} }
Some(_) => return Some(Err("invalid tests list".into())), Some(_) => return Some(Err(format_err!("invalid tests list"))),
None => (), None => (),
} }
@ -645,9 +648,10 @@ impl<'a> Iterator for TestManifest<'a> {
)); ));
} }
Some(term) => { Some(term) => {
return Some(Err( return Some(Err(format_err!(
format!("Invalid tests list. Got term {}", term).into() "Invalid tests list. Got term {}",
)); term
)));
} }
None => (), None => (),
} }

@ -15,8 +15,8 @@ use cpython::Python;
use cpython::PythonObject; use cpython::PythonObject;
use cpython::ToPyObject; use cpython::ToPyObject;
use rudf::model; use rudf::model;
use rudf::Error;
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::error::Error;
use std::hash::Hash; use std::hash::Hash;
use std::hash::Hasher; use std::hash::Hasher;
use std::str::FromStr; use std::str::FromStr;
@ -29,8 +29,8 @@ py_module_initializer!(rudf, initrudf, PyInit_rudf, |py, m| {
Ok(()) Ok(())
}); });
fn new_value_error(py: Python, error: &impl Error) -> PyErr { fn new_value_error(py: Python, error: &Error) -> PyErr {
PyErr::new::<ValueError, _>(py, error.description()) PyErr::new::<ValueError, _>(py, error.to_string())
} }
fn eq_compare<T: Eq + Ord>(a: &T, b: &T, op: &CompareOp) -> bool { fn eq_compare<T: Eq + Ord>(a: &T, b: &T, op: &CompareOp) -> bool {

Loading…
Cancel
Save