use std::fmt;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Violation {
pub code: &'static str,
pub detail: String,
}
impl Violation {
pub(crate) fn new(code: &'static str, detail: impl Into<String>) -> Self {
Self {
code,
detail: detail.into(),
}
}
}
impl fmt::Display for Violation {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}: {}", self.code, self.detail)
}
}
impl std::error::Error for Violation {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ValidationError {
pub code: &'static str,
pub detail: String,
}
impl ValidationError {
pub(crate) fn new(code: &'static str, detail: impl Into<String>) -> Self {
Self {
code,
detail: detail.into(),
}
}
}
impl fmt::Display for ValidationError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}: {}", self.code, self.detail)
}
}
impl std::error::Error for ValidationError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseError {
pub code: &'static str,
pub detail: String,
}
impl ParseError {
pub(crate) fn new(code: &'static str, detail: impl Into<String>) -> Self {
Self {
code,
detail: detail.into(),
}
}
pub(crate) fn malformed(detail: impl Into<String>) -> Self {
Self::new("malformed", detail)
}
}
impl fmt::Display for ParseError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "{}: {}", self.code, self.detail)
}
}
impl std::error::Error for ParseError {}
#[derive(Debug)]
pub enum Error {
Protocol(Violation),
Validation(ValidationError),
Parse(ParseError),
Io(std::io::Error),
HandshakeTimeout,
WriteTimeout,
PublicationQueueFull,
PublicationWorkerFailed,
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Protocol(inner) => write!(formatter, "{inner}"),
Error::Validation(inner) => write!(formatter, "{inner}"),
Error::Parse(inner) => write!(formatter, "{inner}"),
Error::Io(inner) => write!(formatter, "io: {inner}"),
Error::HandshakeTimeout => write!(formatter, "timed out waiting for hello-ack"),
Error::WriteTimeout => {
write!(
formatter,
"the driver did not read within the write deadline"
)
}
Error::PublicationQueueFull => write!(formatter, "semantic publication queue full"),
Error::PublicationWorkerFailed => {
write!(formatter, "semantic publication worker failed")
}
}
}
}
impl std::error::Error for Error {}
impl From<Violation> for Error {
fn from(inner: Violation) -> Self {
Error::Protocol(inner)
}
}
impl From<ValidationError> for Error {
fn from(inner: ValidationError) -> Self {
Error::Validation(inner)
}
}
impl From<ParseError> for Error {
fn from(inner: ParseError) -> Self {
Error::Parse(inner)
}
}
impl From<std::io::Error> for Error {
fn from(inner: std::io::Error) -> Self {
Error::Io(inner)
}
}