use peg::error::ParseError; use peg::str::LineCol; use rio_api::iri::IriParseError; use rio_api::language_tag::LanguageTagParseError; use rio_turtle::TurtleError; use rio_xml::RdfXmlError; use std::error; use std::fmt; use std::io; use std::string::FromUtf8Error; use std::sync::PoisonError; /// The Oxigraph error type. /// /// The `wrap` method allows to make this type wrap any implementation of `std::error::Error`. /// This type also avoids heap allocations for the most common cases of Oxigraph errors. #[derive(Debug)] pub struct Error { inner: ErrorKind, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &self.inner { ErrorKind::Msg { msg } => write!(f, "{}", msg), ErrorKind::Io(e) => e.fmt(f), ErrorKind::FromUtf8(e) => e.fmt(f), ErrorKind::Poison => write!(f, "Mutex was poisoned"), ErrorKind::Iri(e) => e.fmt(f), ErrorKind::LanguageTag(e) => e.fmt(f), ErrorKind::Other(e) => e.fmt(f), } } } impl error::Error for Error { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match &self.inner { ErrorKind::Msg { .. } => None, ErrorKind::Io(e) => Some(e), ErrorKind::FromUtf8(e) => Some(e), ErrorKind::Poison => None, ErrorKind::Iri(e) => Some(e), ErrorKind::LanguageTag(e) => Some(e), ErrorKind::Other(e) => Some(e.as_ref()), } } } impl Error { /// Wraps an other error. pub fn wrap(error: impl error::Error + Send + Sync + 'static) -> Self { Self { inner: ErrorKind::Other(Box::new(error)), } } /// Builds an error from a printable error message. pub fn msg(msg: impl Into) -> Self { Self { inner: ErrorKind::Msg { msg: msg.into() }, } } } #[derive(Debug)] enum ErrorKind { Msg { msg: String }, Io(io::Error), FromUtf8(FromUtf8Error), Poison, Iri(IriParseError), LanguageTag(LanguageTagParseError), Other(Box), } impl From for Error { fn from(error: io::Error) -> Self { Self { inner: ErrorKind::Io(error), } } } impl From for Error { fn from(error: FromUtf8Error) -> Self { Self { inner: ErrorKind::FromUtf8(error), } } } impl From for Error { fn from(error: IriParseError) -> Self { Self { inner: ErrorKind::Iri(error), } } } impl From for Error { fn from(error: LanguageTagParseError) -> Self { Self { inner: ErrorKind::LanguageTag(error), } } } impl From for Error { fn from(error: TurtleError) -> Self { Self::wrap(error) } } impl From for Error { fn from(error: RdfXmlError) -> Self { Self::wrap(error) } } impl From for Error { fn from(error: quick_xml::Error) -> Self { Self::wrap(error) } } impl From> for Error { fn from(error: ParseError) -> Self { Self::wrap(error) } } impl From> for Error { fn from(_: PoisonError) -> Self { Self { inner: ErrorKind::Poison, } } } #[cfg(feature = "rocksdb")] impl From for Error { fn from(error: rocksdb::Error) -> Self { Self::wrap(error) } }