diff --git a/Cargo.toml b/Cargo.toml index 203ae7a1..7e0fe900 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,11 +70,11 @@ zstd = ">=0.12, <0.14" # Internal dependencies oxigraph = { version = "0.4.0-alpha.3-dev", path = "lib/oxigraph" } oxrdf = { version = "0.2.0-alpha.2", path = "lib/oxrdf" } -oxrdfio = { version = "0.1.0-alpha.2", path = "lib/oxrdfio" } -oxrdfxml = { version = "0.1.0-alpha.2", path = "lib/oxrdfxml" } +oxrdfio = { version = "0.1.0-alpha.3-dev", path = "lib/oxrdfio" } +oxrdfxml = { version = "0.1.0-alpha.3-dev", path = "lib/oxrdfxml" } oxrocksdb-sys = { version = "0.4.0-alpha.3-dev", path = "./oxrocksdb-sys" } oxsdatatypes = { version = "0.2.0-alpha.1", path = "lib/oxsdatatypes" } -oxttl = { version = "0.1.0-alpha.2", path = "lib/oxttl" } +oxttl = { version = "0.1.0-alpha.3-dev", path = "lib/oxttl" } sparesults = { version = "0.2.0-alpha.2", path = "lib/sparesults" } spargebra = { version = "0.3.0-alpha.2", path = "lib/spargebra" } sparopt = { version = "0.1.0-alpha.2", path = "lib/sparopt" } diff --git a/lib/oxigraph/src/io/read.rs b/lib/oxigraph/src/io/read.rs index 841b166a..c1c3b332 100644 --- a/lib/oxigraph/src/io/read.rs +++ b/lib/oxigraph/src/io/read.rs @@ -5,7 +5,7 @@ use crate::io::{DatasetFormat, GraphFormat}; use crate::model::*; use oxiri::IriParseError; -use oxrdfio::{FromReadQuadReader, ParseError, RdfParser}; +use oxrdfio::{FromReadQuadReader, RdfParseError, RdfParser}; use std::io::Read; /// Parsers for RDF graph serialization formats. @@ -100,7 +100,7 @@ pub struct TripleReader { } impl Iterator for TripleReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { Some(self.parser.next()?.map(Into::into).map_err(Into::into)) @@ -192,7 +192,7 @@ pub struct QuadReader { } impl Iterator for QuadReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { Some(self.parser.next()?.map_err(Into::into)) diff --git a/lib/oxigraph/src/sparql/algebra.rs b/lib/oxigraph/src/sparql/algebra.rs index 819a9bd9..41689904 100644 --- a/lib/oxigraph/src/sparql/algebra.rs +++ b/lib/oxigraph/src/sparql/algebra.rs @@ -38,7 +38,10 @@ pub struct Query { impl Query { /// Parses a SPARQL query with an optional base IRI to resolve relative IRIs in the query. - pub fn parse(query: &str, base_iri: Option<&str>) -> Result { + pub fn parse( + query: &str, + base_iri: Option<&str>, + ) -> Result { let start = Timer::now(); let query = Self::from(spargebra::Query::parse(query, base_iri)?); Ok(Self { @@ -66,7 +69,7 @@ impl fmt::Display for Query { } impl FromStr for Query { - type Err = spargebra::ParseError; + type Err = spargebra::SparqlSyntaxError; fn from_str(query: &str) -> Result { Self::parse(query, None) @@ -74,7 +77,7 @@ impl FromStr for Query { } impl TryFrom<&str> for Query { - type Error = spargebra::ParseError; + type Error = spargebra::SparqlSyntaxError; fn try_from(query: &str) -> Result { Self::from_str(query) @@ -82,7 +85,7 @@ impl TryFrom<&str> for Query { } impl TryFrom<&String> for Query { - type Error = spargebra::ParseError; + type Error = spargebra::SparqlSyntaxError; fn try_from(query: &String) -> Result { Self::from_str(query) @@ -113,7 +116,7 @@ impl From for Query { /// let update = Update::parse(update_str, None)?; /// /// assert_eq!(update.to_string().trim(), update_str); -/// # Ok::<_, oxigraph::sparql::ParseError>(()) +/// # Ok::<_, oxigraph::sparql::SparqlSyntaxError>(()) /// ``` #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct Update { @@ -123,7 +126,10 @@ pub struct Update { impl Update { /// Parses a SPARQL update with an optional base IRI to resolve relative IRIs in the query. - pub fn parse(update: &str, base_iri: Option<&str>) -> Result { + pub fn parse( + update: &str, + base_iri: Option<&str>, + ) -> Result { let update = spargebra::Update::parse(update, base_iri)?; Ok(Self { using_datasets: update @@ -159,7 +165,7 @@ impl fmt::Display for Update { } impl FromStr for Update { - type Err = spargebra::ParseError; + type Err = spargebra::SparqlSyntaxError; fn from_str(update: &str) -> Result { Self::parse(update, None) @@ -167,7 +173,7 @@ impl FromStr for Update { } impl TryFrom<&str> for Update { - type Error = spargebra::ParseError; + type Error = spargebra::SparqlSyntaxError; fn try_from(update: &str) -> Result { Self::from_str(update) @@ -175,7 +181,7 @@ impl TryFrom<&str> for Update { } impl TryFrom<&String> for Update { - type Error = spargebra::ParseError; + type Error = spargebra::SparqlSyntaxError; fn try_from(update: &String) -> Result { Self::from_str(update) diff --git a/lib/oxigraph/src/sparql/error.rs b/lib/oxigraph/src/sparql/error.rs index 94ee6f57..38731ded 100644 --- a/lib/oxigraph/src/sparql/error.rs +++ b/lib/oxigraph/src/sparql/error.rs @@ -1,7 +1,7 @@ -use crate::io::ParseError as RdfParseError; +use crate::io::RdfParseError; use crate::model::NamedNode; -use crate::sparql::results::ParseError as ResultsParseError; -use crate::sparql::ParseError; +use crate::sparql::results::QueryResultsParseError as ResultsParseError; +use crate::sparql::SparqlSyntaxError; use crate::storage::StorageError; use std::convert::Infallible; use std::error::Error; @@ -13,7 +13,7 @@ use std::io; pub enum EvaluationError { /// An error in SPARQL parsing. #[error(transparent)] - Parsing(#[from] ParseError), + Parsing(#[from] SparqlSyntaxError), /// An error from the storage. #[error(transparent)] Storage(#[from] StorageError), diff --git a/lib/oxigraph/src/sparql/mod.rs b/lib/oxigraph/src/sparql/mod.rs index ec84467f..089f84be 100644 --- a/lib/oxigraph/src/sparql/mod.rs +++ b/lib/oxigraph/src/sparql/mod.rs @@ -25,7 +25,7 @@ use crate::storage::StorageReader; use json_event_parser::{JsonEvent, ToWriteJsonWriter}; pub use oxrdf::{Variable, VariableNameParseError}; use oxsdatatypes::{DayTimeDuration, Float}; -pub use spargebra::ParseError; +pub use spargebra::SparqlSyntaxError; use sparopt::algebra::GraphPattern; use sparopt::Optimizer; use std::collections::HashMap; diff --git a/lib/oxigraph/src/sparql/model.rs b/lib/oxigraph/src/sparql/model.rs index 051f5136..f3624ad5 100644 --- a/lib/oxigraph/src/sparql/model.rs +++ b/lib/oxigraph/src/sparql/model.rs @@ -2,8 +2,8 @@ use crate::io::{RdfFormat, RdfSerializer}; use crate::model::*; use crate::sparql::error::EvaluationError; use crate::sparql::results::{ - FromReadQueryResultsReader, FromReadSolutionsReader, ParseError, QueryResultsFormat, - QueryResultsParser, QueryResultsSerializer, + FromReadQueryResultsReader, FromReadSolutionsReader, QueryResultsFormat, + QueryResultsParseError, QueryResultsParser, QueryResultsSerializer, }; use oxrdf::{Variable, VariableRef}; pub use sparesults::QuerySolution; @@ -22,7 +22,10 @@ pub enum QueryResults { impl QueryResults { /// Reads a SPARQL query results serialization. - pub fn read(read: impl Read + 'static, format: QueryResultsFormat) -> Result { + pub fn read( + read: impl Read + 'static, + format: QueryResultsFormat, + ) -> Result { Ok(QueryResultsParser::from_format(format) .parse_read(read)? .into()) diff --git a/lib/oxigraph/src/storage/error.rs b/lib/oxigraph/src/storage/error.rs index f2f27cdb..d58d0316 100644 --- a/lib/oxigraph/src/storage/error.rs +++ b/lib/oxigraph/src/storage/error.rs @@ -1,4 +1,4 @@ -use crate::io::{ParseError, RdfFormat}; +use crate::io::{RdfFormat, RdfParseError}; use crate::storage::numeric_encoder::EncodedTerm; use oxiri::IriParseError; use oxrdf::TermRef; @@ -83,7 +83,7 @@ impl From for io::Error { pub enum LoaderError { /// An error raised while reading the file. #[error(transparent)] - Parsing(#[from] ParseError), + Parsing(#[from] RdfParseError), /// An error raised during the insertion in the store. #[error(transparent)] Storage(#[from] StorageError), diff --git a/lib/oxigraph/src/store.rs b/lib/oxigraph/src/store.rs index 5b5a1640..d84f5728 100644 --- a/lib/oxigraph/src/store.rs +++ b/lib/oxigraph/src/store.rs @@ -26,7 +26,7 @@ //! # Result::<_, Box>::Ok(()) //! ``` #[cfg(not(target_family = "wasm"))] -use crate::io::ParseError; +use crate::io::RdfParseError; use crate::io::{RdfFormat, RdfParser, RdfSerializer}; use crate::model::*; use crate::sparql::{ @@ -1592,7 +1592,7 @@ impl Iterator for GraphNameIter { #[must_use] pub struct BulkLoader { storage: StorageBulkLoader, - on_parse_error: Option Result<(), ParseError>>>, + on_parse_error: Option Result<(), RdfParseError>>>, } #[cfg(not(target_family = "wasm"))] @@ -1647,7 +1647,7 @@ impl BulkLoader { /// By default the parsing fails. pub fn on_parse_error( mut self, - callback: impl Fn(ParseError) -> Result<(), ParseError> + 'static, + callback: impl Fn(RdfParseError) -> Result<(), RdfParseError> + 'static, ) -> Self { self.on_parse_error = Some(Box::new(callback)); self diff --git a/lib/oxrdfio/Cargo.toml b/lib/oxrdfio/Cargo.toml index 05069df3..427fa559 100644 --- a/lib/oxrdfio/Cargo.toml +++ b/lib/oxrdfio/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxrdfio" -version = "0.1.0-alpha.2" +version = "0.1.0-alpha.3-dev" authors.workspace = true license.workspace = true readme = "README.md" diff --git a/lib/oxrdfio/src/error.rs b/lib/oxrdfio/src/error.rs index cd2c4449..a2d14845 100644 --- a/lib/oxrdfio/src/error.rs +++ b/lib/oxrdfio/src/error.rs @@ -3,61 +3,61 @@ use std::ops::Range; /// Error returned during RDF format parsing. #[derive(Debug, thiserror::Error)] -pub enum ParseError { +pub enum RdfParseError { /// I/O error during parsing (file not found...). #[error(transparent)] Io(#[from] io::Error), /// An error in the file syntax. #[error(transparent)] - Syntax(#[from] SyntaxError), + Syntax(#[from] RdfSyntaxError), } -impl ParseError { +impl RdfParseError { pub(crate) fn msg(msg: &'static str) -> Self { - Self::Syntax(SyntaxError(SyntaxErrorKind::Msg(msg))) + Self::Syntax(RdfSyntaxError(SyntaxErrorKind::Msg(msg))) } } -impl From for SyntaxError { +impl From for RdfSyntaxError { #[inline] - fn from(error: oxttl::SyntaxError) -> Self { + fn from(error: oxttl::TurtleSyntaxError) -> Self { Self(SyntaxErrorKind::Turtle(error)) } } -impl From for ParseError { +impl From for RdfParseError { #[inline] - fn from(error: oxttl::ParseError) -> Self { + fn from(error: oxttl::TurtleParseError) -> Self { match error { - oxttl::ParseError::Syntax(e) => Self::Syntax(e.into()), - oxttl::ParseError::Io(e) => Self::Io(e), + oxttl::TurtleParseError::Syntax(e) => Self::Syntax(e.into()), + oxttl::TurtleParseError::Io(e) => Self::Io(e), } } } -impl From for SyntaxError { +impl From for RdfSyntaxError { #[inline] - fn from(error: oxrdfxml::SyntaxError) -> Self { + fn from(error: oxrdfxml::RdfXmlSyntaxError) -> Self { Self(SyntaxErrorKind::RdfXml(error)) } } -impl From for ParseError { +impl From for RdfParseError { #[inline] - fn from(error: oxrdfxml::ParseError) -> Self { + fn from(error: oxrdfxml::RdfXmlParseError) -> Self { match error { - oxrdfxml::ParseError::Syntax(e) => Self::Syntax(e.into()), - oxrdfxml::ParseError::Io(e) => Self::Io(e), + oxrdfxml::RdfXmlParseError::Syntax(e) => Self::Syntax(e.into()), + oxrdfxml::RdfXmlParseError::Io(e) => Self::Io(e), } } } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: ParseError) -> Self { + fn from(error: RdfParseError) -> Self { match error { - ParseError::Io(error) => error, - ParseError::Syntax(error) => error.into(), + RdfParseError::Io(error) => error, + RdfParseError::Syntax(error) => error.into(), } } } @@ -65,20 +65,20 @@ impl From for io::Error { /// An error in the syntax of the parsed file. #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct SyntaxError(#[from] SyntaxErrorKind); +pub struct RdfSyntaxError(#[from] SyntaxErrorKind); /// An error in the syntax of the parsed file. #[derive(Debug, thiserror::Error)] enum SyntaxErrorKind { #[error(transparent)] - Turtle(#[from] oxttl::SyntaxError), + Turtle(#[from] oxttl::TurtleSyntaxError), #[error(transparent)] - RdfXml(#[from] oxrdfxml::SyntaxError), + RdfXml(#[from] oxrdfxml::RdfXmlSyntaxError), #[error("{0}")] Msg(&'static str), } -impl SyntaxError { +impl RdfSyntaxError { /// The location of the error inside of the file. #[inline] pub fn location(&self) -> Option> { @@ -102,9 +102,9 @@ impl SyntaxError { } } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: SyntaxError) -> Self { + fn from(error: RdfSyntaxError) -> Self { match error.0 { SyntaxErrorKind::Turtle(error) => error.into(), SyntaxErrorKind::RdfXml(error) => error.into(), diff --git a/lib/oxrdfio/src/lib.rs b/lib/oxrdfio/src/lib.rs index 4b51dcf8..b0873f79 100644 --- a/lib/oxrdfio/src/lib.rs +++ b/lib/oxrdfio/src/lib.rs @@ -9,7 +9,7 @@ mod format; mod parser; mod serializer; -pub use error::{ParseError, SyntaxError, TextPosition}; +pub use error::{RdfParseError, RdfSyntaxError, TextPosition}; pub use format::RdfFormat; #[cfg(feature = "async-tokio")] pub use parser::FromTokioAsyncReadQuadReader; diff --git a/lib/oxrdfio/src/parser.rs b/lib/oxrdfio/src/parser.rs index d1536141..5e8f1b8d 100644 --- a/lib/oxrdfio/src/parser.rs +++ b/lib/oxrdfio/src/parser.rs @@ -1,6 +1,6 @@ //! Utilities to read RDF graphs and datasets. -pub use crate::error::ParseError; +pub use crate::error::RdfParseError; use crate::format::RdfFormat; use oxrdf::{BlankNode, GraphName, IriParseError, Quad, Subject, Term, Triple}; #[cfg(feature = "async-tokio")] @@ -310,7 +310,7 @@ impl RdfParser { /// use oxrdfio::{RdfFormat, RdfParser}; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxrdfio::ParseError> { + /// # async fn main() -> Result<(), oxrdfio::RdfParseError> { /// let file = " ."; /// /// let parser = RdfParser::from_format(RdfFormat::NTriples); @@ -396,7 +396,7 @@ enum FromReadQuadReaderKind { } impl Iterator for FromReadQuadReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { Some(match &mut self.parser { @@ -507,7 +507,7 @@ impl FromReadQuadReader { /// use oxrdfio::{RdfFormat, RdfParser}; /// /// # #[tokio::main(flavor = "current_thread")] -/// # async fn main() -> Result<(), oxrdfio::ParseError> { +/// # async fn main() -> Result<(), oxrdfio::RdfParseError> { /// let file = " ."; /// /// let parser = RdfParser::from_format(RdfFormat::NTriples); @@ -537,7 +537,7 @@ enum FromTokioAsyncReadQuadReaderKind { #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadQuadReader { - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { Some(match &mut self.parser { FromTokioAsyncReadQuadReaderKind::N3(parser) => match parser.next().await? { Ok(quad) => self.mapper.map_n3_quad(quad), @@ -578,7 +578,7 @@ impl FromTokioAsyncReadQuadReader { /// use oxrdfio::{RdfFormat, RdfParser}; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -618,7 +618,7 @@ impl FromTokioAsyncReadQuadReader { /// use oxrdfio::{RdfFormat, RdfParser}; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -728,18 +728,18 @@ impl QuadMapper { } } - fn map_graph_name(&mut self, graph_name: GraphName) -> Result { + fn map_graph_name(&mut self, graph_name: GraphName) -> Result { match graph_name { GraphName::NamedNode(node) => { if self.without_named_graphs { - Err(ParseError::msg("Named graphs are not allowed")) + Err(RdfParseError::msg("Named graphs are not allowed")) } else { Ok(node.into()) } } GraphName::BlankNode(node) => { if self.without_named_graphs { - Err(ParseError::msg("Named graphs are not allowed")) + Err(RdfParseError::msg("Named graphs are not allowed")) } else { Ok(self.map_blank_node(node).into()) } @@ -748,7 +748,7 @@ impl QuadMapper { } } - fn map_quad(&mut self, quad: Quad) -> Result { + fn map_quad(&mut self, quad: Quad) -> Result { Ok(Quad { subject: self.map_subject(quad.subject), predicate: quad.predicate, @@ -761,33 +761,33 @@ impl QuadMapper { self.map_triple(triple).in_graph(self.default_graph.clone()) } - fn map_n3_quad(&mut self, quad: N3Quad) -> Result { + fn map_n3_quad(&mut self, quad: N3Quad) -> Result { Ok(Quad { subject: match quad.subject { N3Term::NamedNode(s) => Ok(s.into()), N3Term::BlankNode(s) => Ok(self.map_blank_node(s).into()), - N3Term::Literal(_) => Err(ParseError::msg( + N3Term::Literal(_) => Err(RdfParseError::msg( "literals are not allowed in regular RDF subjects", )), #[cfg(feature = "rdf-star")] N3Term::Triple(s) => Ok(self.map_triple(*s).into()), - N3Term::Variable(_) => Err(ParseError::msg( + N3Term::Variable(_) => Err(RdfParseError::msg( "variables are not allowed in regular RDF subjects", )), }?, predicate: match quad.predicate { N3Term::NamedNode(p) => Ok(p), - N3Term::BlankNode(_) => Err(ParseError::msg( + N3Term::BlankNode(_) => Err(RdfParseError::msg( "blank nodes are not allowed in regular RDF predicates", )), - N3Term::Literal(_) => Err(ParseError::msg( + N3Term::Literal(_) => Err(RdfParseError::msg( "literals are not allowed in regular RDF predicates", )), #[cfg(feature = "rdf-star")] - N3Term::Triple(_) => Err(ParseError::msg( + N3Term::Triple(_) => Err(RdfParseError::msg( "quoted triples are not allowed in regular RDF predicates", )), - N3Term::Variable(_) => Err(ParseError::msg( + N3Term::Variable(_) => Err(RdfParseError::msg( "variables are not allowed in regular RDF predicates", )), }?, @@ -797,7 +797,7 @@ impl QuadMapper { N3Term::Literal(o) => Ok(o.into()), #[cfg(feature = "rdf-star")] N3Term::Triple(o) => Ok(self.map_triple(*o).into()), - N3Term::Variable(_) => Err(ParseError::msg( + N3Term::Variable(_) => Err(RdfParseError::msg( "variables are not allowed in regular RDF objects", )), }?, diff --git a/lib/oxrdfxml/Cargo.toml b/lib/oxrdfxml/Cargo.toml index efc71e62..97dcee82 100644 --- a/lib/oxrdfxml/Cargo.toml +++ b/lib/oxrdfxml/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxrdfxml" -version = "0.1.0-alpha.2" +version = "0.1.0-alpha.3-dev" authors.workspace = true license.workspace = true readme = "README.md" diff --git a/lib/oxrdfxml/src/error.rs b/lib/oxrdfxml/src/error.rs index abc7c55c..9a59a766 100644 --- a/lib/oxrdfxml/src/error.rs +++ b/lib/oxrdfxml/src/error.rs @@ -5,33 +5,33 @@ use std::sync::Arc; /// Error returned during RDF/XML parsing. #[derive(Debug, thiserror::Error)] -pub enum ParseError { +pub enum RdfXmlParseError { /// I/O error during parsing (file not found...). #[error(transparent)] Io(#[from] io::Error), /// An error in the file syntax. #[error(transparent)] - Syntax(#[from] SyntaxError), + Syntax(#[from] RdfXmlSyntaxError), } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: ParseError) -> Self { + fn from(error: RdfXmlParseError) -> Self { match error { - ParseError::Io(error) => error, - ParseError::Syntax(error) => error.into(), + RdfXmlParseError::Io(error) => error, + RdfXmlParseError::Syntax(error) => error.into(), } } } -impl From for ParseError { +impl From for RdfXmlParseError { #[inline] fn from(error: quick_xml::Error) -> Self { match error { quick_xml::Error::Io(error) => { Self::Io(Arc::try_unwrap(error).unwrap_or_else(|e| io::Error::new(e.kind(), e))) } - _ => Self::Syntax(SyntaxError(SyntaxErrorKind::Xml(error))), + _ => Self::Syntax(RdfXmlSyntaxError(SyntaxErrorKind::Xml(error))), } } } @@ -39,7 +39,7 @@ impl From for ParseError { /// An error in the syntax of the parsed file. #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct SyntaxError(#[from] pub(crate) SyntaxErrorKind); +pub struct RdfXmlSyntaxError(#[from] pub(crate) SyntaxErrorKind); #[derive(Debug, thiserror::Error)] pub enum SyntaxErrorKind { @@ -61,7 +61,7 @@ pub enum SyntaxErrorKind { Msg(String), } -impl SyntaxError { +impl RdfXmlSyntaxError { /// Builds an error from a printable error message. #[inline] pub(crate) fn msg(msg: impl Into) -> Self { @@ -69,9 +69,9 @@ impl SyntaxError { } } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: SyntaxError) -> Self { + fn from(error: RdfXmlSyntaxError) -> Self { match error.0 { SyntaxErrorKind::Xml(error) => match error { quick_xml::Error::Io(error) => { diff --git a/lib/oxrdfxml/src/lib.rs b/lib/oxrdfxml/src/lib.rs index bcc87308..2354101a 100644 --- a/lib/oxrdfxml/src/lib.rs +++ b/lib/oxrdfxml/src/lib.rs @@ -9,7 +9,7 @@ mod parser; mod serializer; mod utils; -pub use error::{ParseError, SyntaxError}; +pub use error::{RdfXmlParseError, RdfXmlSyntaxError}; #[cfg(feature = "async-tokio")] pub use parser::FromTokioAsyncReadRdfXmlReader; pub use parser::{FromReadRdfXmlReader, RdfXmlParser}; diff --git a/lib/oxrdfxml/src/parser.rs b/lib/oxrdfxml/src/parser.rs index a952ad02..d11a1f99 100644 --- a/lib/oxrdfxml/src/parser.rs +++ b/lib/oxrdfxml/src/parser.rs @@ -1,4 +1,4 @@ -use crate::error::{ParseError, SyntaxError, SyntaxErrorKind}; +use crate::error::{RdfXmlParseError, RdfXmlSyntaxError, SyntaxErrorKind}; use crate::utils::*; use oxilangtag::LanguageTag; use oxiri::{Iri, IriParseError}; @@ -126,7 +126,7 @@ impl RdfXmlParser { /// use oxrdfxml::RdfXmlParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxrdfxml::ParseError> { + /// # async fn main() -> Result<(), oxrdfxml::RdfXmlParseError> { /// let file = br#" /// /// @@ -214,7 +214,7 @@ pub struct FromReadRdfXmlReader { } impl Iterator for FromReadRdfXmlReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { loop { @@ -236,7 +236,7 @@ impl FromReadRdfXmlReader { self.reader.reader.buffer_position() } - fn parse_step(&mut self) -> Result<(), ParseError> { + fn parse_step(&mut self) -> Result<(), RdfXmlParseError> { self.reader_buffer.clear(); let event = self .reader @@ -255,7 +255,7 @@ impl FromReadRdfXmlReader { /// use oxrdfxml::RdfXmlParser; /// /// # #[tokio::main(flavor = "current_thread")] -/// # async fn main() -> Result<(), oxrdfxml::ParseError> { +/// # async fn main() -> Result<(), oxrdfxml::RdfXmlParseError> { /// let file = br#" /// /// @@ -289,7 +289,7 @@ pub struct FromTokioAsyncReadRdfXmlReader { #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadRdfXmlReader { /// Reads the next triple or returns `None` if the file is finished. - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { loop { if let Some(triple) = self.results.pop() { return Some(Ok(triple)); @@ -307,7 +307,7 @@ impl FromTokioAsyncReadRdfXmlReader { self.reader.reader.buffer_position() } - async fn parse_step(&mut self) -> Result<(), ParseError> { + async fn parse_step(&mut self) -> Result<(), RdfXmlParseError> { self.reader_buffer.clear(); let event = self .reader @@ -440,20 +440,21 @@ impl RdfXmlReader { &mut self, event: Event<'_>, results: &mut Vec, - ) -> Result<(), ParseError> { + ) -> Result<(), RdfXmlParseError> { match event { Event::Start(event) => self.parse_start_event(&event, results), Event::End(event) => self.parse_end_event(&event, results), - Event::Empty(_) => { - Err(SyntaxError::msg("The expand_empty_elements option must be enabled").into()) - } + Event::Empty(_) => Err(RdfXmlSyntaxError::msg( + "The expand_empty_elements option must be enabled", + ) + .into()), Event::Text(event) => self.parse_text_event(&event), Event::CData(event) => self.parse_text_event(&event.escape()?), Event::Comment(_) | Event::PI(_) => Ok(()), Event::Decl(decl) => { if let Some(encoding) = decl.encoding() { if !is_utf8(&encoding?) { - return Err(SyntaxError::msg( + return Err(RdfXmlSyntaxError::msg( "Only UTF-8 is supported by the RDF/XML parser", ) .into()); @@ -469,7 +470,7 @@ impl RdfXmlReader { } } - fn parse_doctype(&mut self, dt: &BytesText<'_>) -> Result<(), ParseError> { + fn parse_doctype(&mut self, dt: &BytesText<'_>) -> Result<(), RdfXmlParseError> { // we extract entities for input in self .reader @@ -481,20 +482,20 @@ impl RdfXmlReader { if let Some(input) = input.strip_prefix("!ENTITY") { let input = input.trim_start().strip_prefix('%').unwrap_or(input); let (entity_name, input) = input.trim_start().split_once(|c: char| c.is_ascii_whitespace()).ok_or_else(|| { - SyntaxError::msg( + RdfXmlSyntaxError::msg( "').ok_or_else(|| { - SyntaxError::msg("") + RdfXmlSyntaxError::msg("") })?; // Resolves custom entities within the current entity definition. @@ -511,7 +512,7 @@ impl RdfXmlReader { &mut self, event: &BytesStart<'_>, results: &mut Vec, - ) -> Result<(), ParseError> { + ) -> Result<(), RdfXmlParseError> { #[derive(PartialEq, Eq)] enum RdfXmlParseType { Default, @@ -576,7 +577,10 @@ impl RdfXmlReader { } else { LanguageTag::parse(tag.to_ascii_lowercase()) .map_err(|error| { - SyntaxError(SyntaxErrorKind::InvalidLanguageTag { tag, error }) + RdfXmlSyntaxError(SyntaxErrorKind::InvalidLanguageTag { + tag, + error, + }) })? .into_inner() }); @@ -588,7 +592,9 @@ impl RdfXmlReader { } else { Iri::parse(iri.clone()) } - .map_err(|error| SyntaxError(SyntaxErrorKind::InvalidIri { iri, error }))?, + .map_err(|error| { + RdfXmlSyntaxError(SyntaxErrorKind::InvalidIri { iri, error }) + })?, ) } else { // We ignore other xml attributes @@ -598,16 +604,17 @@ impl RdfXmlReader { if *attribute_url == *RDF_ID { let mut id = self.convert_attribute(&attribute)?; if !is_nc_name(&id) { - return Err( - SyntaxError::msg(format!("{id} is not a valid rdf:ID value")).into(), - ); + return Err(RdfXmlSyntaxError::msg(format!( + "{id} is not a valid rdf:ID value" + )) + .into()); } id.insert(0, '#'); id_attr = Some(id); } else if *attribute_url == *RDF_BAG_ID { let bag_id = self.convert_attribute(&attribute)?; if !is_nc_name(&bag_id) { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "{bag_id} is not a valid rdf:bagID value" )) .into()); @@ -615,7 +622,7 @@ impl RdfXmlReader { } else if *attribute_url == *RDF_NODE_ID { let id = self.convert_attribute(&attribute)?; if !is_nc_name(&id) { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "{id} is not a valid rdf:nodeID value" )) .into()); @@ -637,7 +644,7 @@ impl RdfXmlReader { } else if attribute_url == rdf::TYPE.as_str() { type_attr = Some(attribute); } else if RESERVED_RDF_ATTRIBUTES.contains(&&*attribute_url) { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "{attribute_url} is not a valid attribute" )) .into()); @@ -655,7 +662,7 @@ impl RdfXmlReader { Some(iri) => { let iri = self.resolve_iri(&base_iri, iri)?; if self.known_rdf_id.contains(iri.as_str()) { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "{iri} has already been used as rdf:ID value" )) .into()); @@ -694,13 +701,14 @@ impl RdfXmlReader { }, Some(RdfXmlState::ParseTypeLiteralPropertyElt { .. }) => { return Err( - SyntaxError::msg("ParseTypeLiteralPropertyElt production children should never be considered as a RDF/XML content").into() + RdfXmlSyntaxError::msg("ParseTypeLiteralPropertyElt production children should never be considered as a RDF/XML content").into() ); } None => { - return Err( - SyntaxError::msg("No state in the stack: the XML is not balanced").into(), - ); + return Err(RdfXmlSyntaxError::msg( + "No state in the stack: the XML is not balanced", + ) + .into()); } }; @@ -709,7 +717,7 @@ impl RdfXmlReader { if *tag_name == *RDF_RDF { RdfXmlState::Rdf { base_iri, language } } else if RESERVED_RDF_ELEMENTS.contains(&&*tag_name) { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "Invalid node element tag name: {tag_name}" )) .into()); @@ -729,7 +737,7 @@ impl RdfXmlReader { } RdfXmlNextProduction::NodeElt => { if RESERVED_RDF_ELEMENTS.contains(&&*tag_name) { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "Invalid property element tag name: {tag_name}" )) .into()); @@ -750,7 +758,7 @@ impl RdfXmlReader { let iri = if *tag_name == *RDF_LI { let Some(RdfXmlState::NodeElt { li_counter, .. }) = self.state.last_mut() else { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "Invalid property element tag name: {tag_name}" )) .into()); @@ -762,7 +770,7 @@ impl RdfXmlReader { } else if RESERVED_RDF_ELEMENTS.contains(&&*tag_name) || *tag_name == *RDF_DESCRIPTION { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "Invalid property element tag name: {tag_name}" )) .into()); @@ -780,7 +788,7 @@ impl RdfXmlReader { (Some(resource_attr), None) => Subject::from(resource_attr), (None, Some(node_id_attr)) => node_id_attr.into(), (None, None) => BlankNode::default().into(), - (Some(_), Some(_)) => return Err(SyntaxError::msg("Not both rdf:resource and rdf:nodeID could be set at the same time").into()) + (Some(_), Some(_)) => return Err(RdfXmlSyntaxError::msg("Not both rdf:resource and rdf:nodeID could be set at the same time").into()) }; Self::emit_property_attrs(&object, property_attrs, &language, results); if let Some(type_attr) = type_attr { @@ -847,7 +855,7 @@ impl RdfXmlReader { &mut self, event: &BytesEnd<'_>, results: &mut Vec, - ) -> Result<(), ParseError> { + ) -> Result<(), RdfXmlParseError> { // Literal case if self.in_literal_depth > 0 { if let Some(RdfXmlState::ParseTypeLiteralPropertyElt { writer, .. }) = @@ -867,7 +875,7 @@ impl RdfXmlReader { Ok(()) } - fn parse_text_event(&mut self, event: &BytesText<'_>) -> Result<(), ParseError> { + fn parse_text_event(&mut self, event: &BytesText<'_>) -> Result<(), RdfXmlParseError> { let text = event.unescape_with(|e| self.resolve_entity(e))?.to_string(); match self.state.last_mut() { Some(RdfXmlState::PropertyElt { object, .. }) => { @@ -884,18 +892,18 @@ impl RdfXmlReader { if event.iter().copied().all(is_whitespace) { Ok(()) } else { - Err(SyntaxError::msg(format!("Unexpected text event: '{text}'")).into()) + Err(RdfXmlSyntaxError::msg(format!("Unexpected text event: '{text}'")).into()) } } } } - fn resolve_tag_name(&self, qname: QName<'_>) -> Result { + fn resolve_tag_name(&self, qname: QName<'_>) -> Result { let (namespace, local_name) = self.reader.resolve_element(qname); self.resolve_ns_name(namespace, local_name) } - fn resolve_attribute_name(&self, qname: QName<'_>) -> Result { + fn resolve_attribute_name(&self, qname: QName<'_>) -> Result { let (namespace, local_name) = self.reader.resolve_attribute(qname); self.resolve_ns_name(namespace, local_name) } @@ -904,7 +912,7 @@ impl RdfXmlReader { &self, namespace: ResolveResult<'_>, local_name: LocalName<'_>, - ) -> Result { + ) -> Result { match namespace { ResolveResult::Bound(ns) => { let mut value = Vec::with_capacity(ns.as_ref().len() + local_name.as_ref().len()); @@ -917,9 +925,9 @@ impl RdfXmlReader { .to_string()) } ResolveResult::Unbound => { - Err(SyntaxError::msg("XML namespaces are required in RDF/XML").into()) + Err(RdfXmlSyntaxError::msg("XML namespaces are required in RDF/XML").into()) } - ResolveResult::Unknown(v) => Err(SyntaxError::msg(format!( + ResolveResult::Unknown(v) => Err(RdfXmlSyntaxError::msg(format!( "Unknown prefix {}:", self.reader.decoder().decode(&v)? )) @@ -938,24 +946,24 @@ impl RdfXmlReader { type_attr: Option, property_attrs: Vec<(NamedNode, String)>, results: &mut Vec, - ) -> Result { + ) -> Result { let subject = match (id_attr, node_id_attr, about_attr) { (Some(id_attr), None, None) => Subject::from(id_attr), (None, Some(node_id_attr), None) => node_id_attr.into(), (None, None, Some(about_attr)) => about_attr.into(), (None, None, None) => BlankNode::default().into(), (Some(_), Some(_), _) => { - return Err(SyntaxError::msg( + return Err(RdfXmlSyntaxError::msg( "Not both rdf:ID and rdf:nodeID could be set at the same time", )) } (_, Some(_), Some(_)) => { - return Err(SyntaxError::msg( + return Err(RdfXmlSyntaxError::msg( "Not both rdf:nodeID and rdf:resource could be set at the same time", )) } (Some(_), _, Some(_)) => { - return Err(SyntaxError::msg( + return Err(RdfXmlSyntaxError::msg( "Not both rdf:ID and rdf:resource could be set at the same time", )) } @@ -1004,7 +1012,7 @@ impl RdfXmlReader { &mut self, state: RdfXmlState, results: &mut Vec, - ) -> Result<(), SyntaxError> { + ) -> Result<(), RdfXmlSyntaxError> { match state { RdfXmlState::PropertyElt { iri, @@ -1059,7 +1067,7 @@ impl RdfXmlReader { if emit { let object = writer.into_inner(); if object.is_empty() { - return Err(SyntaxError::msg(format!( + return Err(RdfXmlSyntaxError::msg(format!( "No value found for rdf:XMLLiteral value of property {iri}" ))); } @@ -1068,7 +1076,9 @@ impl RdfXmlReader { iri, Literal::new_typed_literal( str::from_utf8(&object).map_err(|_| { - SyntaxError::msg("The XML literal is not in valid UTF-8".to_owned()) + RdfXmlSyntaxError::msg( + "The XML literal is not in valid UTF-8".to_owned(), + ) })?, rdf::XML_LITERAL, ), @@ -1141,7 +1151,7 @@ impl RdfXmlReader { } } - fn convert_attribute(&self, attribute: &Attribute<'_>) -> Result { + fn convert_attribute(&self, attribute: &Attribute<'_>) -> Result { Ok(attribute .decode_and_unescape_value_with(&self.reader, |e| self.resolve_entity(e))? .into_owned()) @@ -1151,7 +1161,7 @@ impl RdfXmlReader { &self, base_iri: &Option>, attribute: &Attribute<'_>, - ) -> Result { + ) -> Result { Ok(self.resolve_iri(base_iri, self.convert_attribute(attribute)?)?) } @@ -1159,7 +1169,7 @@ impl RdfXmlReader { &self, base_iri: &Option>, relative_iri: String, - ) -> Result { + ) -> Result { if let Some(base_iri) = base_iri { Ok(NamedNode::new_unchecked( if self.unchecked { @@ -1168,7 +1178,7 @@ impl RdfXmlReader { base_iri.resolve(&relative_iri) } .map_err(|error| { - SyntaxError(SyntaxErrorKind::InvalidIri { + RdfXmlSyntaxError(SyntaxErrorKind::InvalidIri { iri: relative_iri, error, }) @@ -1180,13 +1190,13 @@ impl RdfXmlReader { } } - fn parse_iri(&self, relative_iri: String) -> Result { + fn parse_iri(&self, relative_iri: String) -> Result { Ok(NamedNode::new_unchecked(if self.unchecked { relative_iri } else { Iri::parse(relative_iri.clone()) .map_err(|error| { - SyntaxError(SyntaxErrorKind::InvalidIri { + RdfXmlSyntaxError(SyntaxErrorKind::InvalidIri { iri: relative_iri, error, }) diff --git a/lib/oxttl/Cargo.toml b/lib/oxttl/Cargo.toml index 0a4bc3ab..c86150ed 100644 --- a/lib/oxttl/Cargo.toml +++ b/lib/oxttl/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "oxttl" -version = "0.1.0-alpha.2" +version = "0.1.0-alpha.3-dev" authors.workspace = true license.workspace = true readme = "README.md" diff --git a/lib/oxttl/src/lib.rs b/lib/oxttl/src/lib.rs index 0e04e243..a1dd95f9 100644 --- a/lib/oxttl/src/lib.rs +++ b/lib/oxttl/src/lib.rs @@ -17,7 +17,7 @@ pub mod turtle; pub use crate::n3::N3Parser; pub use crate::nquads::{NQuadsParser, NQuadsSerializer}; pub use crate::ntriples::{NTriplesParser, NTriplesSerializer}; -pub use crate::toolkit::{ParseError, SyntaxError, TextPosition}; +pub use crate::toolkit::{TextPosition, TurtleParseError, TurtleSyntaxError}; pub use crate::trig::{TriGParser, TriGSerializer}; pub use crate::turtle::{TurtleParser, TurtleSerializer}; diff --git a/lib/oxttl/src/n3.rs b/lib/oxttl/src/n3.rs index 8b70a01e..de3e9363 100644 --- a/lib/oxttl/src/n3.rs +++ b/lib/oxttl/src/n3.rs @@ -4,9 +4,9 @@ use crate::lexer::{resolve_local_name, N3Lexer, N3LexerMode, N3LexerOptions, N3T #[cfg(feature = "async-tokio")] use crate::toolkit::FromTokioAsyncReadIterator; use crate::toolkit::{ - FromReadIterator, Lexer, Parser, RuleRecognizer, RuleRecognizerError, SyntaxError, + FromReadIterator, Lexer, Parser, RuleRecognizer, RuleRecognizerError, TurtleSyntaxError, }; -use crate::{ParseError, MAX_BUFFER_SIZE, MIN_BUFFER_SIZE}; +use crate::{TurtleParseError, MAX_BUFFER_SIZE, MIN_BUFFER_SIZE}; use oxiri::{Iri, IriParseError}; use oxrdf::vocab::{rdf, xsd}; #[cfg(feature = "rdf-star")] @@ -291,7 +291,7 @@ impl N3Parser { /// use oxttl::n3::{N3Parser, N3Term}; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -461,7 +461,7 @@ impl FromReadN3Reader { } impl Iterator for FromReadN3Reader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { self.inner.next() @@ -477,7 +477,7 @@ impl Iterator for FromReadN3Reader { /// use oxttl::n3::{N3Parser, N3Term}; /// /// # #[tokio::main(flavor = "current_thread")] -/// # async fn main() -> Result<(), oxttl::ParseError> { +/// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -508,7 +508,7 @@ pub struct FromTokioAsyncReadN3Reader { #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadN3Reader { /// Reads the next triple or returns `None` if the file is finished. - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { Some(self.inner.next().await?.map(Into::into)) } @@ -522,7 +522,7 @@ impl FromTokioAsyncReadN3Reader { /// use oxttl::N3Parser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -551,7 +551,7 @@ impl FromTokioAsyncReadN3Reader { /// use oxttl::N3Parser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -641,7 +641,7 @@ impl LowLevelN3Reader { /// /// Returns [`None`] if the parsing is finished or more data is required. /// If it is the case more data should be fed using [`extend_from_slice`](Self::extend_from_slice). - pub fn read_next(&mut self) -> Option> { + pub fn read_next(&mut self) -> Option> { self.parser.read_next() } diff --git a/lib/oxttl/src/nquads.rs b/lib/oxttl/src/nquads.rs index 0ae22119..9f48bc76 100644 --- a/lib/oxttl/src/nquads.rs +++ b/lib/oxttl/src/nquads.rs @@ -4,7 +4,7 @@ use crate::line_formats::NQuadsRecognizer; #[cfg(feature = "async-tokio")] use crate::toolkit::FromTokioAsyncReadIterator; -use crate::toolkit::{FromReadIterator, ParseError, Parser, SyntaxError}; +use crate::toolkit::{FromReadIterator, Parser, TurtleParseError, TurtleSyntaxError}; use oxrdf::{Quad, QuadRef}; use std::io::{self, Read, Write}; #[cfg(feature = "async-tokio")] @@ -106,7 +106,7 @@ impl NQuadsParser { /// use oxttl::NQuadsParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#" . /// "Foo" . /// . @@ -213,7 +213,7 @@ pub struct FromReadNQuadsReader { } impl Iterator for FromReadNQuadsReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { self.inner.next() @@ -228,7 +228,7 @@ impl Iterator for FromReadNQuadsReader { /// use oxttl::NQuadsParser; /// /// # #[tokio::main(flavor = "current_thread")] -/// # async fn main() -> Result<(), oxttl::ParseError> { +/// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#" . /// "Foo" . /// . @@ -256,7 +256,7 @@ pub struct FromTokioAsyncReadNQuadsReader { #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadNQuadsReader { /// Reads the next triple or returns `None` if the file is finished. - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { Some(self.inner.next().await?.map(Into::into)) } } @@ -323,7 +323,7 @@ impl LowLevelNQuadsReader { /// /// Returns [`None`] if the parsing is finished or more data is required. /// If it is the case more data should be fed using [`extend_from_slice`](Self::extend_from_slice). - pub fn read_next(&mut self) -> Option> { + pub fn read_next(&mut self) -> Option> { self.parser.read_next() } } diff --git a/lib/oxttl/src/ntriples.rs b/lib/oxttl/src/ntriples.rs index 686907dc..ca033959 100644 --- a/lib/oxttl/src/ntriples.rs +++ b/lib/oxttl/src/ntriples.rs @@ -4,7 +4,7 @@ use crate::line_formats::NQuadsRecognizer; #[cfg(feature = "async-tokio")] use crate::toolkit::FromTokioAsyncReadIterator; -use crate::toolkit::{FromReadIterator, ParseError, Parser, SyntaxError}; +use crate::toolkit::{FromReadIterator, Parser, TurtleParseError, TurtleSyntaxError}; use oxrdf::{Triple, TripleRef}; use std::io::{self, Read, Write}; #[cfg(feature = "async-tokio")] @@ -106,7 +106,7 @@ impl NTriplesParser { /// use oxttl::NTriplesParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#" . /// "Foo" . /// . @@ -213,7 +213,7 @@ pub struct FromReadNTriplesReader { } impl Iterator for FromReadNTriplesReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { Some(self.inner.next()?.map(Into::into)) @@ -228,7 +228,7 @@ impl Iterator for FromReadNTriplesReader { /// use oxttl::NTriplesParser; /// /// # #[tokio::main(flavor = "current_thread")] -/// # async fn main() -> Result<(), oxttl::ParseError> { +/// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#" . /// "Foo" . /// . @@ -256,7 +256,7 @@ pub struct FromTokioAsyncReadNTriplesReader { #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadNTriplesReader { /// Reads the next triple or returns `None` if the file is finished. - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { Some(self.inner.next().await?.map(Into::into)) } } @@ -323,7 +323,7 @@ impl LowLevelNTriplesReader { /// /// Returns [`None`] if the parsing is finished or more data is required. /// If it is the case more data should be fed using [`extend_from_slice`](Self::extend_from_slice). - pub fn read_next(&mut self) -> Option> { + pub fn read_next(&mut self) -> Option> { Some(self.parser.read_next()?.map(Into::into)) } } diff --git a/lib/oxttl/src/toolkit/error.rs b/lib/oxttl/src/toolkit/error.rs index 33f2a916..083adefa 100644 --- a/lib/oxttl/src/toolkit/error.rs +++ b/lib/oxttl/src/toolkit/error.rs @@ -13,12 +13,12 @@ pub struct TextPosition { /// /// It is composed of a message and a byte range in the input. #[derive(Debug, thiserror::Error)] -pub struct SyntaxError { +pub struct TurtleSyntaxError { pub(super) location: Range, pub(super) message: String, } -impl SyntaxError { +impl TurtleSyntaxError { /// The location of the error inside of the file. #[inline] pub fn location(&self) -> Range { @@ -32,7 +32,7 @@ impl SyntaxError { } } -impl fmt::Display for SyntaxError { +impl fmt::Display for TurtleSyntaxError { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.location.start.offset + 1 >= self.location.end.offset { @@ -66,32 +66,32 @@ impl fmt::Display for SyntaxError { } } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: SyntaxError) -> Self { + fn from(error: TurtleSyntaxError) -> Self { Self::new(io::ErrorKind::InvalidData, error) } } /// A parsing error. /// -/// It is the union of [`SyntaxError`] and [`io::Error`]. +/// It is the union of [`TurtleSyntaxError`] and [`io::Error`]. #[derive(Debug, thiserror::Error)] -pub enum ParseError { +pub enum TurtleParseError { /// I/O error during parsing (file not found...). #[error(transparent)] Io(#[from] io::Error), /// An error in the file syntax. #[error(transparent)] - Syntax(#[from] SyntaxError), + Syntax(#[from] TurtleSyntaxError), } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: ParseError) -> Self { + fn from(error: TurtleParseError) -> Self { match error { - ParseError::Syntax(e) => e.into(), - ParseError::Io(e) => e, + TurtleParseError::Syntax(e) => e.into(), + TurtleParseError::Io(e) => e, } } } diff --git a/lib/oxttl/src/toolkit/lexer.rs b/lib/oxttl/src/toolkit/lexer.rs index 2406dfb1..4db73fae 100644 --- a/lib/oxttl/src/toolkit/lexer.rs +++ b/lib/oxttl/src/toolkit/lexer.rs @@ -1,4 +1,4 @@ -use crate::toolkit::error::{SyntaxError, TextPosition}; +use crate::toolkit::error::{TextPosition, TurtleSyntaxError}; use memchr::{memchr2, memchr2_iter}; use std::borrow::Cow; use std::cmp::min; @@ -163,7 +163,10 @@ impl Lexer { } #[allow(clippy::unwrap_in_result)] - pub fn read_next(&mut self, options: &R::Options) -> Option, SyntaxError>> { + pub fn read_next( + &mut self, + options: &R::Options, + ) -> Option, TurtleSyntaxError>> { self.skip_whitespaces_and_comments()?; self.previous_position = self.position; let Some((consumed, result)) = self.parser.recognize_next_token( @@ -194,7 +197,7 @@ impl Lexer { ), offset: self.position.global_offset, }; - let error = SyntaxError { + let error = TurtleSyntaxError { location: new_position..new_position, message: "Unexpected end of file".into(), }; @@ -224,7 +227,7 @@ impl Lexer { self.position.buffer_offset += consumed; self.position.global_offset += u64::try_from(consumed).unwrap(); self.position.global_line += new_line_jumps; - Some(result.map_err(|e| SyntaxError { + Some(result.map_err(|e| TurtleSyntaxError { location: self.location_from_buffer_offset_range(e.location), message: e.message, })) diff --git a/lib/oxttl/src/toolkit/mod.rs b/lib/oxttl/src/toolkit/mod.rs index cc8e3624..10c42163 100644 --- a/lib/oxttl/src/toolkit/mod.rs +++ b/lib/oxttl/src/toolkit/mod.rs @@ -6,7 +6,7 @@ mod error; mod lexer; mod parser; -pub use self::error::{ParseError, SyntaxError, TextPosition}; +pub use self::error::{TextPosition, TurtleParseError, TurtleSyntaxError}; pub use self::lexer::{Lexer, TokenRecognizer, TokenRecognizerError}; #[cfg(feature = "async-tokio")] pub use self::parser::FromTokioAsyncReadIterator; diff --git a/lib/oxttl/src/toolkit/parser.rs b/lib/oxttl/src/toolkit/parser.rs index 6314640d..6ac8a1ac 100644 --- a/lib/oxttl/src/toolkit/parser.rs +++ b/lib/oxttl/src/toolkit/parser.rs @@ -1,4 +1,4 @@ -use crate::toolkit::error::{ParseError, SyntaxError}; +use crate::toolkit::error::{TurtleParseError, TurtleSyntaxError}; use crate::toolkit::lexer::{Lexer, TokenRecognizer}; use std::io::Read; #[cfg(feature = "async-tokio")] @@ -77,10 +77,10 @@ impl Parser { self.state.is_none() && self.results.is_empty() && self.errors.is_empty() } - pub fn read_next(&mut self) -> Option> { + pub fn read_next(&mut self) -> Option> { loop { if let Some(error) = self.errors.pop() { - return Some(Err(SyntaxError { + return Some(Err(TurtleSyntaxError { location: self.lexer.last_token_location(), message: error .message @@ -141,12 +141,12 @@ pub struct FromReadIterator { } impl Iterator for FromReadIterator { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { while !self.parser.is_end() { if let Some(result) = self.parser.read_next() { - return Some(result.map_err(ParseError::Syntax)); + return Some(result.map_err(TurtleParseError::Syntax)); } if let Err(e) = self.parser.lexer.extend_from_read(&mut self.read) { return Some(Err(e.into())); @@ -164,10 +164,10 @@ pub struct FromTokioAsyncReadIterator #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadIterator { - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { while !self.parser.is_end() { if let Some(result) = self.parser.read_next() { - return Some(result.map_err(ParseError::Syntax)); + return Some(result.map_err(TurtleParseError::Syntax)); } if let Err(e) = self .parser diff --git a/lib/oxttl/src/trig.rs b/lib/oxttl/src/trig.rs index 21434ed4..e230b9be 100644 --- a/lib/oxttl/src/trig.rs +++ b/lib/oxttl/src/trig.rs @@ -5,7 +5,7 @@ use crate::lexer::N3Lexer; use crate::terse::TriGRecognizer; #[cfg(feature = "async-tokio")] use crate::toolkit::FromTokioAsyncReadIterator; -use crate::toolkit::{FromReadIterator, ParseError, Parser, SyntaxError}; +use crate::toolkit::{FromReadIterator, Parser, TurtleParseError, TurtleSyntaxError}; use oxiri::{Iri, IriParseError}; use oxrdf::vocab::{rdf, xsd}; use oxrdf::{ @@ -140,7 +140,7 @@ impl TriGParser { /// use oxttl::TriGParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -314,7 +314,7 @@ impl FromReadTriGReader { } impl Iterator for FromReadTriGReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { self.inner.next() @@ -330,7 +330,7 @@ impl Iterator for FromReadTriGReader { /// use oxttl::TriGParser; /// /// # #[tokio::main(flavor = "current_thread")] -/// # async fn main() -> Result<(), oxttl::ParseError> { +/// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -360,7 +360,7 @@ pub struct FromTokioAsyncReadTriGReader { #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadTriGReader { /// Reads the next triple or returns `None` if the file is finished. - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { Some(self.inner.next().await?.map(Into::into)) } @@ -374,7 +374,7 @@ impl FromTokioAsyncReadTriGReader { /// use oxttl::TriGParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -403,7 +403,7 @@ impl FromTokioAsyncReadTriGReader { /// use oxttl::TriGParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -492,7 +492,7 @@ impl LowLevelTriGReader { /// /// Returns [`None`] if the parsing is finished or more data is required. /// If it is the case more data should be fed using [`extend_from_slice`](Self::extend_from_slice). - pub fn read_next(&mut self) -> Option> { + pub fn read_next(&mut self) -> Option> { self.parser.read_next() } diff --git a/lib/oxttl/src/turtle.rs b/lib/oxttl/src/turtle.rs index 0cc9fd77..eb972224 100644 --- a/lib/oxttl/src/turtle.rs +++ b/lib/oxttl/src/turtle.rs @@ -4,7 +4,7 @@ use crate::terse::TriGRecognizer; #[cfg(feature = "async-tokio")] use crate::toolkit::FromTokioAsyncReadIterator; -use crate::toolkit::{FromReadIterator, ParseError, Parser, SyntaxError}; +use crate::toolkit::{FromReadIterator, Parser, TurtleParseError, TurtleSyntaxError}; #[cfg(feature = "async-tokio")] use crate::trig::ToTokioAsyncWriteTriGWriter; use crate::trig::{LowLevelTriGWriter, ToWriteTriGWriter, TriGSerializer}; @@ -138,7 +138,7 @@ impl TurtleParser { /// use oxttl::TurtleParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -312,7 +312,7 @@ impl FromReadTurtleReader { } impl Iterator for FromReadTurtleReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { Some(self.inner.next()?.map(Into::into)) @@ -328,7 +328,7 @@ impl Iterator for FromReadTurtleReader { /// use oxttl::TurtleParser; /// /// # #[tokio::main(flavor = "current_thread")] -/// # async fn main() -> Result<(), oxttl::ParseError> { +/// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -358,7 +358,7 @@ pub struct FromTokioAsyncReadTurtleReader { #[cfg(feature = "async-tokio")] impl FromTokioAsyncReadTurtleReader { /// Reads the next triple or returns `None` if the file is finished. - pub async fn next(&mut self) -> Option> { + pub async fn next(&mut self) -> Option> { Some(self.inner.next().await?.map(Into::into)) } @@ -372,7 +372,7 @@ impl FromTokioAsyncReadTurtleReader { /// use oxttl::TurtleParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -401,7 +401,7 @@ impl FromTokioAsyncReadTurtleReader { /// use oxttl::TurtleParser; /// /// # #[tokio::main(flavor = "current_thread")] - /// # async fn main() -> Result<(), oxttl::ParseError> { + /// # async fn main() -> Result<(), oxttl::TurtleParseError> { /// let file = br#"@base . /// @prefix schema: . /// a schema:Person ; @@ -490,7 +490,7 @@ impl LowLevelTurtleReader { /// /// Returns [`None`] if the parsing is finished or more data is required. /// If it is the case more data should be fed using [`extend_from_slice`](Self::extend_from_slice). - pub fn read_next(&mut self) -> Option> { + pub fn read_next(&mut self) -> Option> { Some(self.parser.read_next()?.map(Into::into)) } diff --git a/lib/sparesults/src/csv.rs b/lib/sparesults/src/csv.rs index bd2fe4b1..02f4df9b 100644 --- a/lib/sparesults/src/csv.rs +++ b/lib/sparesults/src/csv.rs @@ -1,6 +1,8 @@ //! Implementation of [SPARQL 1.1 Query Results CSV and TSV Formats](https://www.w3.org/TR/sparql11-results-csv-tsv/) -use crate::error::{ParseError, SyntaxError, SyntaxErrorKind, TextPosition}; +use crate::error::{ + QueryResultsParseError, QueryResultsSyntaxError, SyntaxErrorKind, TextPosition, +}; use memchr::memchr; use oxrdf::vocab::xsd; use oxrdf::*; @@ -432,7 +434,7 @@ pub enum TsvQueryResultsReader { } impl TsvQueryResultsReader { - pub fn read(mut read: R) -> Result { + pub fn read(mut read: R) -> Result { let mut reader = LineReader::new(); let mut buffer = Vec::new(); @@ -451,13 +453,13 @@ impl TsvQueryResultsReader { for v in line.split('\t') { let v = v.trim(); if v.is_empty() { - return Err(SyntaxError::msg("Empty column on the first row. The first row should be a list of variables like ?foo or $bar").into()); + return Err(QueryResultsSyntaxError::msg("Empty column on the first row. The first row should be a list of variables like ?foo or $bar").into()); } let variable = Variable::from_str(v).map_err(|e| { - SyntaxError::msg(format!("Invalid variable declaration '{v}': {e}")) + QueryResultsSyntaxError::msg(format!("Invalid variable declaration '{v}': {e}")) })?; if variables.contains(&variable) { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "The variable {variable} is declared twice" )) .into()); @@ -487,7 +489,7 @@ pub struct TsvSolutionsReader { impl TsvSolutionsReader { #[allow(clippy::unwrap_in_result)] - pub fn read_next(&mut self) -> Result>>, ParseError> { + pub fn read_next(&mut self) -> Result>>, QueryResultsParseError> { let line = self.reader.next_line(&mut self.buffer, &mut self.read)?; if line.is_empty() { return Ok(None); // EOF @@ -508,35 +510,33 @@ impl TsvSolutionsReader { .sum::(); let start_position_bytes = line.split('\t').take(i).map(|c| c.len() + 1).sum::(); - SyntaxError { - inner: SyntaxErrorKind::Term { - error: e, - term: v.into(), - location: TextPosition { - line: self.reader.line_count - 1, - column: start_position_char.try_into().unwrap(), - offset: self.reader.last_line_start - + u64::try_from(start_position_bytes).unwrap(), - }..TextPosition { - line: self.reader.line_count - 1, - column: (start_position_char + v.chars().count()) - .try_into() - .unwrap(), - offset: self.reader.last_line_start - + u64::try_from(start_position_bytes + v.len()).unwrap(), - }, + QueryResultsSyntaxError(SyntaxErrorKind::Term { + error: e, + term: v.into(), + location: TextPosition { + line: self.reader.line_count - 1, + column: start_position_char.try_into().unwrap(), + offset: self.reader.last_line_start + + u64::try_from(start_position_bytes).unwrap(), + }..TextPosition { + line: self.reader.line_count - 1, + column: (start_position_char + v.chars().count()) + .try_into() + .unwrap(), + offset: self.reader.last_line_start + + u64::try_from(start_position_bytes + v.len()).unwrap(), }, - } + }) })?)) } }) - .collect::, ParseError>>()?; + .collect::, QueryResultsParseError>>()?; if elements.len() == self.column_len { Ok(Some(elements)) } else if self.column_len == 0 && elements == [None] { Ok(Some(Vec::new())) // Zero columns case } else { - Err(SyntaxError::located_message( + Err(QueryResultsSyntaxError::located_message( format!( "This TSV files has {} columns but we found a row on line {} with {} columns: {}", self.column_len, diff --git a/lib/sparesults/src/error.rs b/lib/sparesults/src/error.rs index cc5a1e4a..f26a3349 100644 --- a/lib/sparesults/src/error.rs +++ b/lib/sparesults/src/error.rs @@ -5,44 +5,44 @@ use std::sync::Arc; /// Error returned during SPARQL result formats format parsing. #[derive(Debug, thiserror::Error)] -pub enum ParseError { +pub enum QueryResultsParseError { /// I/O error during parsing (file not found...). #[error(transparent)] Io(#[from] io::Error), /// An error in the file syntax. #[error(transparent)] - Syntax(#[from] SyntaxError), + Syntax(#[from] QueryResultsSyntaxError), } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: ParseError) -> Self { + fn from(error: QueryResultsParseError) -> Self { match error { - ParseError::Io(error) => error, - ParseError::Syntax(error) => error.into(), + QueryResultsParseError::Io(error) => error, + QueryResultsParseError::Syntax(error) => error.into(), } } } -impl From for ParseError { +impl From for QueryResultsParseError { fn from(error: json_event_parser::ParseError) -> Self { match error { - json_event_parser::ParseError::Syntax(error) => SyntaxError::from(error).into(), + json_event_parser::ParseError::Syntax(error) => { + QueryResultsSyntaxError::from(error).into() + } json_event_parser::ParseError::Io(error) => error.into(), } } } -impl From for ParseError { +impl From for QueryResultsParseError { #[inline] fn from(error: quick_xml::Error) -> Self { match error { quick_xml::Error::Io(error) => { Self::Io(Arc::try_unwrap(error).unwrap_or_else(|e| io::Error::new(e.kind(), e))) } - _ => Self::Syntax(SyntaxError { - inner: SyntaxErrorKind::Xml(error), - }), + _ => Self::Syntax(QueryResultsSyntaxError(SyntaxErrorKind::Xml(error))), } } } @@ -50,10 +50,7 @@ impl From for ParseError { /// An error in the syntax of the parsed file. #[derive(Debug, thiserror::Error)] #[error(transparent)] -pub struct SyntaxError { - #[from] - pub(crate) inner: SyntaxErrorKind, -} +pub struct QueryResultsSyntaxError(#[from] pub(crate) SyntaxErrorKind); #[derive(Debug, thiserror::Error)] pub(crate) enum SyntaxErrorKind { @@ -75,33 +72,29 @@ pub(crate) enum SyntaxErrorKind { }, } -impl SyntaxError { +impl QueryResultsSyntaxError { /// Builds an error from a printable error message. #[inline] pub(crate) fn msg(msg: impl Into) -> Self { - Self { - inner: SyntaxErrorKind::Msg { - msg: msg.into(), - location: None, - }, - } + Self(SyntaxErrorKind::Msg { + msg: msg.into(), + location: None, + }) } /// Builds an error from a printable error message and a location #[inline] pub(crate) fn located_message(msg: impl Into, location: Range) -> Self { - Self { - inner: SyntaxErrorKind::Msg { - msg: msg.into(), - location: Some(location), - }, - } + Self(SyntaxErrorKind::Msg { + msg: msg.into(), + location: Some(location), + }) } /// The location of the error inside of the file. #[inline] pub fn location(&self) -> Option> { - match &self.inner { + match &self.0 { SyntaxErrorKind::Json(e) => { let location = e.location(); Some( @@ -123,10 +116,10 @@ impl SyntaxError { } } -impl From for io::Error { +impl From for io::Error { #[inline] - fn from(error: SyntaxError) -> Self { - match error.inner { + fn from(error: QueryResultsSyntaxError) -> Self { + match error.0 { SyntaxErrorKind::Json(error) => Self::new(io::ErrorKind::InvalidData, error), SyntaxErrorKind::Xml(error) => match error { quick_xml::Error::Io(error) => { @@ -143,11 +136,9 @@ impl From for io::Error { } } -impl From for SyntaxError { +impl From for QueryResultsSyntaxError { fn from(error: json_event_parser::SyntaxError) -> Self { - Self { - inner: SyntaxErrorKind::Json(error), - } + Self(SyntaxErrorKind::Json(error)) } } diff --git a/lib/sparesults/src/json.rs b/lib/sparesults/src/json.rs index 2e63fc81..25da2d64 100644 --- a/lib/sparesults/src/json.rs +++ b/lib/sparesults/src/json.rs @@ -1,6 +1,6 @@ //! Implementation of [SPARQL Query Results JSON Format](https://www.w3.org/TR/sparql11-results-json/) -use crate::error::{ParseError, SyntaxError}; +use crate::error::{QueryResultsParseError, QueryResultsSyntaxError}; #[cfg(feature = "async-tokio")] use json_event_parser::ToTokioAsyncWriteJsonWriter; use json_event_parser::{FromReadJsonReader, JsonEvent, ToWriteJsonWriter}; @@ -233,14 +233,16 @@ pub enum JsonQueryResultsReader { } impl JsonQueryResultsReader { - pub fn read(read: R) -> Result { + pub fn read(read: R) -> Result { let mut reader = FromReadJsonReader::new(read); let mut variables = None; let mut buffered_bindings: Option> = None; let mut output_iter = None; if reader.read_next_event()? != JsonEvent::StartObject { - return Err(SyntaxError::msg("SPARQL JSON results should be an object").into()); + return Err( + QueryResultsSyntaxError::msg("SPARQL JSON results should be an object").into(), + ); } loop { @@ -269,14 +271,17 @@ impl JsonQueryResultsReader { } "results" => { if reader.read_next_event()? != JsonEvent::StartObject { - return Err(SyntaxError::msg("'results' should be an object").into()); + return Err(QueryResultsSyntaxError::msg( + "'results' should be an object", + ) + .into()); } loop { match reader.read_next_event()? { JsonEvent::ObjectKey(k) if k == "bindings" => break, // Found JsonEvent::ObjectKey(_) => ignore_value(&mut reader)?, _ => { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "'results' should contain a 'bindings' key", ) .into()) @@ -284,7 +289,10 @@ impl JsonQueryResultsReader { } } if reader.read_next_event()? != JsonEvent::StartArray { - return Err(SyntaxError::msg("'bindings' should be an object").into()); + return Err(QueryResultsSyntaxError::msg( + "'bindings' should be an object", + ) + .into()); } if let Some(variables) = variables { let mut mapping = BTreeMap::default(); @@ -318,9 +326,10 @@ impl JsonQueryResultsReader { values.push(read_value(&mut reader, 0)?); } _ => { - return Err( - SyntaxError::msg("Invalid result serialization").into() + return Err(QueryResultsSyntaxError::msg( + "Invalid result serialization", ) + .into()) } } } @@ -329,11 +338,11 @@ impl JsonQueryResultsReader { return if let JsonEvent::Boolean(v) = reader.read_next_event()? { Ok(Self::Boolean(v)) } else { - Err(SyntaxError::msg("Unexpected boolean value").into()) + Err(QueryResultsSyntaxError::msg("Unexpected boolean value").into()) } } _ => { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Expecting head or result key, found {key}" )) .into()); @@ -344,13 +353,18 @@ impl JsonQueryResultsReader { return if let Some(output_iter) = output_iter { Ok(output_iter) } else { - Err(SyntaxError::msg( + Err(QueryResultsSyntaxError::msg( "Unexpected end of JSON object without 'results' or 'boolean' key", ) .into()) } } - _ => return Err(SyntaxError::msg("Invalid SPARQL results serialization").into()), + _ => { + return Err(QueryResultsSyntaxError::msg( + "Invalid SPARQL results serialization", + ) + .into()) + } } } } @@ -371,7 +385,7 @@ enum JsonSolutionsReaderKind { } impl JsonSolutionsReader { - pub fn read_next(&mut self) -> Result>>, ParseError> { + pub fn read_next(&mut self) -> Result>>, QueryResultsParseError> { match &mut self.kind { JsonSolutionsReaderKind::Streaming { reader } => { let mut new_bindings = vec![None; self.mapping.len()]; @@ -382,13 +396,18 @@ impl JsonSolutionsReader { JsonEvent::EndArray | JsonEvent::Eof => return Ok(None), JsonEvent::ObjectKey(key) => { let k = *self.mapping.get(key.as_ref()).ok_or_else(|| { - SyntaxError::msg(format!( + QueryResultsSyntaxError::msg(format!( "The variable {key} has not been defined in the header" )) })?; new_bindings[k] = Some(read_value(reader, 0)?) } - _ => return Err(SyntaxError::msg("Invalid result serialization").into()), + _ => { + return Err(QueryResultsSyntaxError::msg( + "Invalid result serialization", + ) + .into()) + } } } } @@ -397,7 +416,7 @@ impl JsonSolutionsReader { let mut new_bindings = vec![None; self.mapping.len()]; for (variable, value) in variables.into_iter().zip(values) { let k = *self.mapping.get(&variable).ok_or_else(|| { - SyntaxError::msg(format!( + QueryResultsSyntaxError::msg(format!( "The variable {variable} has not been defined in the header" )) })?; @@ -415,7 +434,7 @@ impl JsonSolutionsReader { fn read_value( reader: &mut FromReadJsonReader, number_of_recursive_calls: usize, -) -> Result { +) -> Result { enum Type { Uri, BNode, @@ -432,7 +451,7 @@ fn read_value( } if number_of_recursive_calls == MAX_NUMBER_OF_NESTED_TRIPLES { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Too many nested triples ({MAX_NUMBER_OF_NESTED_TRIPLES}). The parser fails here to avoid a stack overflow." )) .into()); @@ -449,7 +468,7 @@ fn read_value( #[cfg(feature = "rdf-star")] let mut object = None; if reader.read_next_event()? != JsonEvent::StartObject { - return Err(SyntaxError::msg("Term serializations should be an object").into()); + return Err(QueryResultsSyntaxError::msg("Term serializations should be an object").into()); } loop { #[allow(unsafe_code)] @@ -472,7 +491,7 @@ fn read_value( #[cfg(feature = "rdf-star")] "object" => object = Some(read_value(reader, number_of_recursive_calls + 1)?), _ => { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Unexpected key in term serialization: '{key}'" )) .into()) @@ -480,9 +499,10 @@ fn read_value( }, JsonEvent::StartObject => { if state != Some(State::Value) { - return Err( - SyntaxError::msg("Unexpected nested object in term serialization").into(), - ); + return Err(QueryResultsSyntaxError::msg( + "Unexpected nested object in term serialization", + ) + .into()); } } JsonEvent::String(s) => match state { @@ -494,9 +514,10 @@ fn read_value( #[cfg(feature = "rdf-star")] "triple" => t = Some(Type::Triple), _ => { - return Err( - SyntaxError::msg(format!("Unexpected term type: '{s}'")).into() - ) + return Err(QueryResultsSyntaxError::msg(format!( + "Unexpected term type: '{s}'" + )) + .into()) } }; state = None; @@ -510,10 +531,9 @@ fn read_value( state = None; } Some(State::Datatype) => { - datatype = Some( - NamedNode::new(s) - .map_err(|e| SyntaxError::msg(format!("Invalid datatype IRI: {e}")))?, - ); + datatype = Some(NamedNode::new(s).map_err(|e| { + QueryResultsSyntaxError::msg(format!("Invalid datatype IRI: {e}")) + })?); state = None; } _ => (), // impossible @@ -523,41 +543,52 @@ fn read_value( if s == State::Value { state = None; // End of triple } else { - return Err( - SyntaxError::msg("Term description values should be string").into() - ); + return Err(QueryResultsSyntaxError::msg( + "Term description values should be string", + ) + .into()); } } else { return match t { - None => Err(SyntaxError::msg( + None => Err(QueryResultsSyntaxError::msg( "Term serialization should have a 'type' key", ) .into()), Some(Type::Uri) => Ok(NamedNode::new(value.ok_or_else(|| { - SyntaxError::msg("uri serialization should have a 'value' key") + QueryResultsSyntaxError::msg( + "uri serialization should have a 'value' key", + ) })?) - .map_err(|e| SyntaxError::msg(format!("Invalid uri value: {e}")))? + .map_err(|e| { + QueryResultsSyntaxError::msg(format!("Invalid uri value: {e}")) + })? .into()), Some(Type::BNode) => Ok(BlankNode::new(value.ok_or_else(|| { - SyntaxError::msg("bnode serialization should have a 'value' key") + QueryResultsSyntaxError::msg( + "bnode serialization should have a 'value' key", + ) })?) - .map_err(|e| SyntaxError::msg(format!("Invalid bnode value: {e}")))? + .map_err(|e| { + QueryResultsSyntaxError::msg(format!("Invalid bnode value: {e}")) + })? .into()), Some(Type::Literal) => { let value = value.ok_or_else(|| { - SyntaxError::msg("literal serialization should have a 'value' key") + QueryResultsSyntaxError::msg( + "literal serialization should have a 'value' key", + ) })?; Ok(match lang { Some(lang) => { if let Some(datatype) = datatype { if datatype.as_ref() != rdf::LANG_STRING { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "xml:lang value '{lang}' provided with the datatype {datatype}" )).into()) } } Literal::new_language_tagged_literal(value, &*lang).map_err(|e| { - SyntaxError::msg(format!("Invalid xml:lang value '{lang}': {e}")) + QueryResultsSyntaxError::msg(format!("Invalid xml:lang value '{lang}': {e}")) })? } None => if let Some(datatype) = datatype { @@ -571,47 +602,53 @@ fn read_value( #[cfg(feature = "rdf-star")] Some(Type::Triple) => Ok(Triple::new( match subject.ok_or_else(|| { - SyntaxError::msg("triple serialization should have a 'subject' key") + QueryResultsSyntaxError::msg( + "triple serialization should have a 'subject' key", + ) })? { Term::NamedNode(subject) => subject.into(), Term::BlankNode(subject) => subject.into(), Term::Triple(subject) => Subject::Triple(subject), Term::Literal(_) => { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "The 'subject' value should not be a literal", ) .into()) } }, match predicate.ok_or_else(|| { - SyntaxError::msg( + QueryResultsSyntaxError::msg( "triple serialization should have a 'predicate' key", ) })? { Term::NamedNode(predicate) => predicate, _ => { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "The 'predicate' value should be a uri", ) .into()) } }, object.ok_or_else(|| { - SyntaxError::msg("triple serialization should have a 'object' key") + QueryResultsSyntaxError::msg( + "triple serialization should have a 'object' key", + ) })?, ) .into()), }; } } - _ => return Err(SyntaxError::msg("Invalid term serialization").into()), + _ => return Err(QueryResultsSyntaxError::msg("Invalid term serialization").into()), } } } -fn read_head(reader: &mut FromReadJsonReader) -> Result, ParseError> { +fn read_head( + reader: &mut FromReadJsonReader, +) -> Result, QueryResultsParseError> { if reader.read_next_event()? != JsonEvent::StartObject { - return Err(SyntaxError::msg("head should be an object").into()); + return Err(QueryResultsSyntaxError::msg("head should be an object").into()); } let mut variables = Vec::new(); loop { @@ -619,18 +656,21 @@ fn read_head(reader: &mut FromReadJsonReader) -> Result match key.as_ref() { "vars" => { if reader.read_next_event()? != JsonEvent::StartArray { - return Err(SyntaxError::msg("Variable list should be an array").into()); + return Err(QueryResultsSyntaxError::msg( + "Variable list should be an array", + ) + .into()); } loop { match reader.read_next_event()? { JsonEvent::String(s) => { let new_var = Variable::new(s.as_ref()).map_err(|e| { - SyntaxError::msg(format!( + QueryResultsSyntaxError::msg(format!( "Invalid variable declaration '{s}': {e}" )) })?; if variables.contains(&new_var) { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "The variable {new_var} is declared twice" )) .into()); @@ -639,23 +679,30 @@ fn read_head(reader: &mut FromReadJsonReader) -> Result break, _ => { - return Err( - SyntaxError::msg("Variable names should be strings").into() + return Err(QueryResultsSyntaxError::msg( + "Variable names should be strings", ) + .into()) } } } } "link" => { if reader.read_next_event()? != JsonEvent::StartArray { - return Err(SyntaxError::msg("Variable list should be an array").into()); + return Err(QueryResultsSyntaxError::msg( + "Variable list should be an array", + ) + .into()); } loop { match reader.read_next_event()? { JsonEvent::String(_) => (), JsonEvent::EndArray => break, _ => { - return Err(SyntaxError::msg("Link names should be strings").into()) + return Err(QueryResultsSyntaxError::msg( + "Link names should be strings", + ) + .into()) } } } @@ -663,12 +710,12 @@ fn read_head(reader: &mut FromReadJsonReader) -> Result ignore_value(reader)?, }, JsonEvent::EndObject => return Ok(variables), - _ => return Err(SyntaxError::msg("Invalid head serialization").into()), + _ => return Err(QueryResultsSyntaxError::msg("Invalid head serialization").into()), } } } -fn ignore_value(reader: &mut FromReadJsonReader) -> Result<(), ParseError> { +fn ignore_value(reader: &mut FromReadJsonReader) -> Result<(), QueryResultsParseError> { let mut nesting = 0; loop { match reader.read_next_event()? { @@ -688,7 +735,9 @@ fn ignore_value(reader: &mut FromReadJsonReader) -> Result<(), Parse return Ok(()); } } - JsonEvent::Eof => return Err(SyntaxError::msg("Unexpected end of file").into()), + JsonEvent::Eof => { + return Err(QueryResultsSyntaxError::msg("Unexpected end of file").into()) + } } } } diff --git a/lib/sparesults/src/lib.rs b/lib/sparesults/src/lib.rs index 301dc2c8..ea3135c4 100644 --- a/lib/sparesults/src/lib.rs +++ b/lib/sparesults/src/lib.rs @@ -13,7 +13,7 @@ mod serializer; pub mod solution; mod xml; -pub use crate::error::{ParseError, SyntaxError, TextPosition}; +pub use crate::error::{QueryResultsParseError, QueryResultsSyntaxError, TextPosition}; pub use crate::format::QueryResultsFormat; pub use crate::parser::{FromReadQueryResultsReader, FromReadSolutionsReader, QueryResultsParser}; pub use crate::serializer::{QueryResultsSerializer, ToWriteSolutionsWriter}; diff --git a/lib/sparesults/src/parser.rs b/lib/sparesults/src/parser.rs index 3332335b..f95d9355 100644 --- a/lib/sparesults/src/parser.rs +++ b/lib/sparesults/src/parser.rs @@ -1,5 +1,5 @@ use crate::csv::{TsvQueryResultsReader, TsvSolutionsReader}; -use crate::error::{ParseError, SyntaxError}; +use crate::error::{QueryResultsParseError, QueryResultsSyntaxError}; use crate::format::QueryResultsFormat; use crate::json::{JsonQueryResultsReader, JsonSolutionsReader}; use crate::solution::QuerySolution; @@ -32,7 +32,7 @@ use std::sync::Arc; /// assert_eq!(solution?.iter().collect::>(), vec![(&Variable::new_unchecked("foo"), &Literal::from("test").into())]); /// } /// } -/// # Result::<(),sparesults::ParseError>::Ok(()) +/// # Result::<(),sparesults::QueryResultsParseError>::Ok(()) /// ``` pub struct QueryResultsParser { format: QueryResultsFormat, @@ -68,12 +68,12 @@ impl QueryResultsParser { /// assert_eq!(solution?.iter().collect::>(), vec![(&Variable::new_unchecked("foo"), &Literal::from("test").into())]); /// } /// } - /// # Result::<(),sparesults::ParseError>::Ok(()) + /// # Result::<(),sparesults::QueryResultsParseError>::Ok(()) /// ``` pub fn parse_read( &self, reader: R, - ) -> Result, ParseError> { + ) -> Result, QueryResultsParseError> { Ok(match self.format { QueryResultsFormat::Xml => match XmlQueryResultsReader::read(reader)? { XmlQueryResultsReader::Boolean(r) => FromReadQueryResultsReader::Boolean(r), @@ -95,7 +95,7 @@ impl QueryResultsParser { solutions: SolutionsReaderKind::Json(solutions), }), }, - QueryResultsFormat::Csv => return Err(SyntaxError::msg("CSV SPARQL results syntax is lossy and can't be parsed to a proper RDF representation").into()), + QueryResultsFormat::Csv => return Err(QueryResultsSyntaxError::msg("CSV SPARQL results syntax is lossy and can't be parsed to a proper RDF representation").into()), QueryResultsFormat::Tsv => match TsvQueryResultsReader::read(reader)? { TsvQueryResultsReader::Boolean(r) => FromReadQueryResultsReader::Boolean(r), TsvQueryResultsReader::Solutions { @@ -113,7 +113,7 @@ impl QueryResultsParser { pub fn read_results( &self, reader: R, - ) -> Result, ParseError> { + ) -> Result, QueryResultsParseError> { self.parse_read(reader) } } @@ -161,7 +161,7 @@ impl From for QueryResultsParser { /// ); /// } /// } -/// # Result::<(),sparesults::ParseError>::Ok(()) +/// # Result::<(),sparesults::QueryResultsParseError>::Ok(()) /// ``` pub enum FromReadQueryResultsReader { Solutions(FromReadSolutionsReader), @@ -184,7 +184,7 @@ pub enum FromReadQueryResultsReader { /// assert_eq!(solution?.iter().collect::>(), vec![(&Variable::new_unchecked("foo"), &Literal::from("test").into())]); /// } /// } -/// # Result::<(),sparesults::ParseError>::Ok(()) +/// # Result::<(),sparesults::QueryResultsParseError>::Ok(()) /// ``` pub struct FromReadSolutionsReader { variables: Arc<[Variable]>, @@ -217,7 +217,7 @@ impl FromReadSolutionsReader { /// ] /// ); /// } - /// # Result::<(),sparesults::ParseError>::Ok(()) + /// # Result::<(),sparesults::QueryResultsParseError>::Ok(()) /// ``` #[inline] pub fn variables(&self) -> &[Variable] { @@ -226,7 +226,7 @@ impl FromReadSolutionsReader { } impl Iterator for FromReadSolutionsReader { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { Some( diff --git a/lib/sparesults/src/xml.rs b/lib/sparesults/src/xml.rs index fb038d2d..6eb861e2 100644 --- a/lib/sparesults/src/xml.rs +++ b/lib/sparesults/src/xml.rs @@ -1,6 +1,6 @@ //! Implementation of [SPARQL Query Results XML Format](https://www.w3.org/TR/rdf-sparql-XMLres/) -use crate::error::{ParseError, SyntaxError}; +use crate::error::{QueryResultsParseError, QueryResultsSyntaxError}; use oxrdf::vocab::rdf; use oxrdf::*; use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, BytesText, Event}; @@ -227,7 +227,7 @@ pub enum XmlQueryResultsReader { } impl XmlQueryResultsReader { - pub fn read(source: R) -> Result { + pub fn read(source: R) -> Result { enum State { Start, Sparql, @@ -254,14 +254,14 @@ impl XmlQueryResultsReader { if event.local_name().as_ref() == b"sparql" { state = State::Sparql; } else { - return Err(SyntaxError::msg(format!("Expecting tag, found <{}>", decode(&reader, &event.name())?)).into()); + return Err(QueryResultsSyntaxError::msg(format!("Expecting tag, found <{}>", decode(&reader, &event.name())?)).into()); } } State::Sparql => { if event.local_name().as_ref() == b"head" { state = State::Head; } else { - return Err(SyntaxError::msg(format!("Expecting tag, found <{}>",decode(&reader, &event.name())?)).into()); + return Err(QueryResultsSyntaxError::msg(format!("Expecting tag, found <{}>", decode(&reader, &event.name())?)).into()); } } State::Head => { @@ -269,11 +269,11 @@ impl XmlQueryResultsReader { let name = event.attributes() .filter_map(Result::ok) .find(|attr| attr.key.local_name().as_ref() == b"name") - .ok_or_else(|| SyntaxError::msg("No name attribute found for the tag"))? + .ok_or_else(|| QueryResultsSyntaxError::msg("No name attribute found for the tag"))? .decode_and_unescape_value(&reader)?; - let variable = Variable::new(name).map_err(|e| SyntaxError::msg(format!("Invalid variable name: {e}")))?; + let variable = Variable::new(name).map_err(|e| QueryResultsSyntaxError::msg(format!("Invalid variable name: {e}")))?; if variables.contains(&variable) { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "The variable {variable} is declared twice" )) .into()); @@ -282,7 +282,7 @@ impl XmlQueryResultsReader { } else if event.local_name().as_ref() == b"link" { // no op } else { - return Err(SyntaxError::msg(format!("Expecting or tag, found <{}>", decode(&reader, &event.name())?)).into()); + return Err(QueryResultsSyntaxError::msg(format!("Expecting or tag, found <{}>", decode(&reader, &event.name())?)).into()); } } State::AfterHead => { @@ -304,10 +304,10 @@ impl XmlQueryResultsReader { object_stack: Vec::new(), }}); } else if event.local_name().as_ref() != b"link" && event.local_name().as_ref() != b"results" && event.local_name().as_ref() != b"boolean" { - return Err(SyntaxError::msg(format!("Expecting sparql tag, found <{}>", decode(&reader, &event.name())?)).into()); + return Err(QueryResultsSyntaxError::msg(format!("Expecting sparql tag, found <{}>", decode(&reader, &event.name())?)).into()); } } - State::Boolean => return Err(SyntaxError::msg(format!("Unexpected tag inside of tag: <{}>", decode(&reader, &event.name())?)).into()) + State::Boolean => return Err(QueryResultsSyntaxError::msg(format!("Unexpected tag inside of tag: <{}>", decode(&reader, &event.name())?)).into()) }, Event::Text(event) => { let value = event.unescape()?; @@ -318,10 +318,10 @@ impl XmlQueryResultsReader { } else if value == "false" { Ok(Self::Boolean(false)) } else { - Err(SyntaxError::msg(format!("Unexpected boolean value. Found '{value}'")).into()) + Err(QueryResultsSyntaxError::msg(format!("Unexpected boolean value. Found '{value}'")).into()) }; } - _ => Err(SyntaxError::msg(format!("Unexpected textual value found: '{value}'")).into()) + _ => Err(QueryResultsSyntaxError::msg(format!("Unexpected textual value found: '{value}'")).into()) }; }, Event::End(event) => { @@ -330,10 +330,10 @@ impl XmlQueryResultsReader { state = State::AfterHead } } else { - return Err(SyntaxError::msg("Unexpected early file end. All results file should have a and a or tag").into()); + return Err(QueryResultsSyntaxError::msg("Unexpected early file end. All results file should have a and a or tag").into()); } }, - Event::Eof => return Err(SyntaxError::msg("Unexpected early file end. All results file should have a and a or tag").into()), + Event::Eof => return Err(QueryResultsSyntaxError::msg("Unexpected early file end. All results file should have a and a or tag").into()), _ => (), } } @@ -365,7 +365,7 @@ pub struct XmlSolutionsReader { } impl XmlSolutionsReader { - pub fn read_next(&mut self) -> Result>>, ParseError> { + pub fn read_next(&mut self) -> Result>>, QueryResultsParseError> { let mut state = State::Start; let mut new_bindings = vec![None; self.mapping.len()]; @@ -383,7 +383,7 @@ impl XmlSolutionsReader { if event.local_name().as_ref() == b"result" { state = State::Result; } else { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Expecting , found <{}>", decode(&self.reader, &event.name())? )) @@ -403,7 +403,7 @@ impl XmlSolutionsReader { ) } None => { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "No name attribute found for the tag", ) .into()); @@ -411,7 +411,7 @@ impl XmlSolutionsReader { } state = State::Binding; } else { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Expecting , found <{}>", decode(&self.reader, &event.name())? )) @@ -420,7 +420,7 @@ impl XmlSolutionsReader { } State::Binding | State::Subject | State::Predicate | State::Object => { if term.is_some() { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "There is already a value for the current binding", ) .into()); @@ -441,7 +441,7 @@ impl XmlSolutionsReader { let iri = attr.decode_and_unescape_value(&self.reader)?; datatype = Some(NamedNode::new(iri.to_string()).map_err(|e| { - SyntaxError::msg(format!( + QueryResultsSyntaxError::msg(format!( "Invalid datatype IRI '{iri}': {e}" )) })?); @@ -451,7 +451,7 @@ impl XmlSolutionsReader { } else if event.local_name().as_ref() == b"triple" { state = State::Triple; } else { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Expecting , or found <{}>", decode(&self.reader, &event.name())? )) @@ -466,7 +466,7 @@ impl XmlSolutionsReader { } else if event.local_name().as_ref() == b"object" { state = State::Object } else { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Expecting , or found <{}>", decode(&self.reader, &event.name())? )) @@ -482,7 +482,9 @@ impl XmlSolutionsReader { term = Some( NamedNode::new(data.to_string()) .map_err(|e| { - SyntaxError::msg(format!("Invalid IRI value '{data}': {e}")) + QueryResultsSyntaxError::msg(format!( + "Invalid IRI value '{data}': {e}" + )) })? .into(), ) @@ -491,7 +493,7 @@ impl XmlSolutionsReader { term = Some( BlankNode::new(data.to_string()) .map_err(|e| { - SyntaxError::msg(format!( + QueryResultsSyntaxError::msg(format!( "Invalid blank node value '{data}': {e}" )) })? @@ -502,7 +504,7 @@ impl XmlSolutionsReader { term = Some(build_literal(data, lang.take(), datatype.take())?.into()); } _ => { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "Unexpected textual value found: {data}" )) .into()); @@ -518,11 +520,14 @@ impl XmlSolutionsReader { new_bindings[*var] = term.take() } else { return Err( - SyntaxError::msg(format!("The variable '{var}' is used in a binding but not declared in the variables list")).into() + QueryResultsSyntaxError::msg(format!("The variable '{var}' is used in a binding but not declared in the variables list")).into() ); } } else { - return Err(SyntaxError::msg("No name found for tag").into()); + return Err(QueryResultsSyntaxError::msg( + "No name found for tag", + ) + .into()); } state = State::Result; } @@ -548,7 +553,7 @@ impl XmlSolutionsReader { state = self .stack .pop() - .ok_or_else(|| SyntaxError::msg("Empty stack"))? + .ok_or_else(|| QueryResultsSyntaxError::msg("Empty stack"))? } State::BNode => { if term.is_none() { @@ -558,7 +563,7 @@ impl XmlSolutionsReader { state = self .stack .pop() - .ok_or_else(|| SyntaxError::msg("Empty stack"))? + .ok_or_else(|| QueryResultsSyntaxError::msg("Empty stack"))? } State::Literal => { if term.is_none() { @@ -568,7 +573,7 @@ impl XmlSolutionsReader { state = self .stack .pop() - .ok_or_else(|| SyntaxError::msg("Empty stack"))?; + .ok_or_else(|| QueryResultsSyntaxError::msg("Empty stack"))?; } State::Triple => { #[cfg(feature = "rdf-star")] @@ -584,7 +589,7 @@ impl XmlSolutionsReader { Term::BlankNode(subject) => subject.into(), Term::Triple(subject) => Subject::Triple(subject), Term::Literal(_) => { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "The value should not be a ", ) .into()) @@ -593,7 +598,7 @@ impl XmlSolutionsReader { match predicate { Term::NamedNode(predicate) => predicate, _ => { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "The value should be an ", ) .into()) @@ -606,15 +611,15 @@ impl XmlSolutionsReader { state = self .stack .pop() - .ok_or_else(|| SyntaxError::msg("Empty stack"))?; + .ok_or_else(|| QueryResultsSyntaxError::msg("Empty stack"))?; } else { return Err( - SyntaxError::msg("A should contain a , a and an ").into() + QueryResultsSyntaxError::msg("A should contain a , a and an ").into() ); } #[cfg(not(feature = "rdf-star"))] { - return Err(SyntaxError::msg( + return Err(QueryResultsSyntaxError::msg( "The tag is only supported with RDF-star", ) .into()); @@ -633,19 +638,19 @@ fn build_literal( value: impl Into, lang: Option, datatype: Option, -) -> Result { +) -> Result { match lang { Some(lang) => { if let Some(datatype) = datatype { if datatype.as_ref() != rdf::LANG_STRING { - return Err(SyntaxError::msg(format!( + return Err(QueryResultsSyntaxError::msg(format!( "xml:lang value '{lang}' provided with the datatype {datatype}" )) .into()); } } Literal::new_language_tagged_literal(value, &lang).map_err(|e| { - SyntaxError::msg(format!("Invalid xml:lang value '{lang}': {e}")).into() + QueryResultsSyntaxError::msg(format!("Invalid xml:lang value '{lang}': {e}")).into() }) } None => Ok(if let Some(datatype) = datatype { @@ -659,7 +664,7 @@ fn build_literal( fn decode<'a, T>( reader: &Reader, data: &'a impl AsRef<[u8]>, -) -> Result, ParseError> { +) -> Result, QueryResultsParseError> { Ok(reader.decoder().decode(data.as_ref())?) } diff --git a/lib/spargebra/src/lib.rs b/lib/spargebra/src/lib.rs index e2d093f3..654de4ee 100644 --- a/lib/spargebra/src/lib.rs +++ b/lib/spargebra/src/lib.rs @@ -10,6 +10,6 @@ mod query; pub mod term; mod update; -pub use parser::ParseError; +pub use parser::SparqlSyntaxError; pub use query::*; pub use update::*; diff --git a/lib/spargebra/src/parser.rs b/lib/spargebra/src/parser.rs index a0a8e9d1..8e5d7445 100644 --- a/lib/spargebra/src/parser.rs +++ b/lib/spargebra/src/parser.rs @@ -15,16 +15,16 @@ use std::mem::take; use std::str::FromStr; /// Parses a SPARQL query with an optional base IRI to resolve relative IRIs in the query. -pub fn parse_query(query: &str, base_iri: Option<&str>) -> Result { +pub fn parse_query(query: &str, base_iri: Option<&str>) -> Result { let mut state = ParserState::from_base_iri(base_iri)?; - parser::QueryUnit(query, &mut state).map_err(|e| ParseError(ParseErrorKind::Parser(e))) + parser::QueryUnit(query, &mut state).map_err(|e| SparqlSyntaxError(ParseErrorKind::Syntax(e))) } /// Parses a SPARQL update with an optional base IRI to resolve relative IRIs in the query. -pub fn parse_update(update: &str, base_iri: Option<&str>) -> Result { +pub fn parse_update(update: &str, base_iri: Option<&str>) -> Result { let mut state = ParserState::from_base_iri(base_iri)?; let operations = parser::UpdateInit(update, &mut state) - .map_err(|e| ParseError(ParseErrorKind::Parser(e)))?; + .map_err(|e| SparqlSyntaxError(ParseErrorKind::Syntax(e)))?; Ok(Update { operations, base_iri: state.base_iri, @@ -34,14 +34,14 @@ pub fn parse_update(update: &str, base_iri: Option<&str>) -> Result), + Syntax(#[from] peg::error::ParseError), } struct AnnotatedTerm { @@ -669,12 +669,12 @@ pub struct ParserState { } impl ParserState { - pub(crate) fn from_base_iri(base_iri: Option<&str>) -> Result { + pub(crate) fn from_base_iri(base_iri: Option<&str>) -> Result { Ok(Self { base_iri: if let Some(base_iri) = base_iri { Some( Iri::parse(base_iri.to_owned()) - .map_err(|e| ParseError(ParseErrorKind::InvalidBaseIri(e)))?, + .map_err(|e| SparqlSyntaxError(ParseErrorKind::InvalidBaseIri(e)))?, ) } else { None diff --git a/lib/spargebra/src/query.rs b/lib/spargebra/src/query.rs index 780455f7..108221fa 100644 --- a/lib/spargebra/src/query.rs +++ b/lib/spargebra/src/query.rs @@ -1,5 +1,5 @@ use crate::algebra::*; -use crate::parser::{parse_query, ParseError}; +use crate::parser::{parse_query, SparqlSyntaxError}; use crate::term::*; use oxiri::Iri; use std::fmt; @@ -17,7 +17,7 @@ use std::str::FromStr; /// query.to_sse(), /// "(project (?s ?p ?o) (bgp (triple ?s ?p ?o)))" /// ); -/// # Ok::<_, spargebra::ParseError>(()) +/// # Ok::<_, spargebra::SparqlSyntaxError>(()) /// ``` #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub enum Query { @@ -63,7 +63,7 @@ pub enum Query { impl Query { /// Parses a SPARQL query with an optional base IRI to resolve relative IRIs in the query. - pub fn parse(query: &str, base_iri: Option<&str>) -> Result { + pub fn parse(query: &str, base_iri: Option<&str>) -> Result { parse_query(query, base_iri) } @@ -276,7 +276,7 @@ impl fmt::Display for Query { } impl FromStr for Query { - type Err = ParseError; + type Err = SparqlSyntaxError; fn from_str(query: &str) -> Result { Self::parse(query, None) @@ -284,7 +284,7 @@ impl FromStr for Query { } impl<'a> TryFrom<&'a str> for Query { - type Error = ParseError; + type Error = SparqlSyntaxError; fn try_from(query: &str) -> Result { Self::from_str(query) @@ -292,7 +292,7 @@ impl<'a> TryFrom<&'a str> for Query { } impl<'a> TryFrom<&'a String> for Query { - type Error = ParseError; + type Error = SparqlSyntaxError; fn try_from(query: &String) -> Result { Self::from_str(query) diff --git a/lib/spargebra/src/update.rs b/lib/spargebra/src/update.rs index 76c5c65d..8f57c985 100644 --- a/lib/spargebra/src/update.rs +++ b/lib/spargebra/src/update.rs @@ -1,5 +1,5 @@ use crate::algebra::*; -use crate::parser::{parse_update, ParseError}; +use crate::parser::{parse_update, SparqlSyntaxError}; use crate::term::*; use oxiri::Iri; use std::fmt; @@ -14,7 +14,7 @@ use std::str::FromStr; /// let update = Update::parse(update_str, None)?; /// assert_eq!(update.to_string().trim(), update_str); /// assert_eq!(update.to_sse(), "(update (clear all))"); -/// # Ok::<_, spargebra::ParseError>(()) +/// # Ok::<_, spargebra::SparqlSyntaxError>(()) /// ``` #[derive(Eq, PartialEq, Debug, Clone, Hash)] pub struct Update { @@ -26,7 +26,7 @@ pub struct Update { impl Update { /// Parses a SPARQL update with an optional base IRI to resolve relative IRIs in the query. - pub fn parse(update: &str, base_iri: Option<&str>) -> Result { + pub fn parse(update: &str, base_iri: Option<&str>) -> Result { parse_update(update, base_iri) } @@ -68,7 +68,7 @@ impl fmt::Display for Update { } impl FromStr for Update { - type Err = ParseError; + type Err = SparqlSyntaxError; fn from_str(update: &str) -> Result { Self::parse(update, None) @@ -76,7 +76,7 @@ impl FromStr for Update { } impl<'a> TryFrom<&'a str> for Update { - type Error = ParseError; + type Error = SparqlSyntaxError; fn try_from(update: &str) -> Result { Self::from_str(update) @@ -84,7 +84,7 @@ impl<'a> TryFrom<&'a str> for Update { } impl<'a> TryFrom<&'a String> for Update { - type Error = ParseError; + type Error = SparqlSyntaxError; fn try_from(update: &String) -> Result { Self::from_str(update) diff --git a/python/src/io.rs b/python/src/io.rs index bf3a4383..37d97451 100644 --- a/python/src/io.rs +++ b/python/src/io.rs @@ -1,7 +1,7 @@ #![allow(clippy::needless_option_as_deref)] use crate::model::{hash, PyQuad, PyTriple}; -use oxigraph::io::{FromReadQuadReader, ParseError, RdfFormat, RdfParser, RdfSerializer}; +use oxigraph::io::{FromReadQuadReader, RdfFormat, RdfParseError, RdfParser, RdfSerializer}; use oxigraph::model::QuadRef; use pyo3::exceptions::{PyDeprecationWarning, PySyntaxError, PyValueError}; use pyo3::intern; @@ -556,9 +556,9 @@ pub enum PyRdfFormatInput { MediaType(String), } -pub fn map_parse_error(error: ParseError, file_path: Option) -> PyErr { +pub fn map_parse_error(error: RdfParseError, file_path: Option) -> PyErr { match error { - ParseError::Syntax(error) => { + RdfParseError::Syntax(error) => { // Python 3.9 does not support end line and end column if python_version() >= (3, 10) { let params = if let Some(location) = error.location() { @@ -588,7 +588,7 @@ pub fn map_parse_error(error: ParseError, file_path: Option) -> PyErr { PySyntaxError::new_err((error.to_string(), params)) } } - ParseError::Io(error) => error.into(), + RdfParseError::Io(error) => error.into(), } } diff --git a/python/src/sparql.rs b/python/src/sparql.rs index 383a7413..b1133fa1 100644 --- a/python/src/sparql.rs +++ b/python/src/sparql.rs @@ -4,8 +4,8 @@ use crate::store::map_storage_error; use oxigraph::io::RdfSerializer; use oxigraph::model::Term; use oxigraph::sparql::results::{ - FromReadQueryResultsReader, FromReadSolutionsReader, ParseError, QueryResultsFormat, - QueryResultsParser, QueryResultsSerializer, + FromReadQueryResultsReader, FromReadSolutionsReader, QueryResultsFormat, + QueryResultsParseError, QueryResultsParser, QueryResultsSerializer, }; use oxigraph::sparql::{ EvaluationError, Query, QueryResults, QuerySolution, QuerySolutionIter, QueryTripleIter, @@ -699,9 +699,12 @@ pub fn map_evaluation_error(error: EvaluationError) -> PyErr { } } -pub fn map_query_results_parse_error(error: ParseError, file_path: Option) -> PyErr { +pub fn map_query_results_parse_error( + error: QueryResultsParseError, + file_path: Option, +) -> PyErr { match error { - ParseError::Syntax(error) => { + QueryResultsParseError::Syntax(error) => { // Python 3.9 does not support end line and end column if python_version() >= (3, 10) { let params = if let Some(location) = error.location() { @@ -731,6 +734,6 @@ pub fn map_query_results_parse_error(error: ParseError, file_path: Option error.into(), + QueryResultsParseError::Io(error) => error.into(), } }