#![allow(single_use_lifetimes)]
use std::io;
use std::num::ParseIntError;
use crate::{pipeline::Pipeline, query::Query};
#[allow(clippy::module_name_repetitions)]
#[derive(Debug, PartialEq, Eq, thiserror::Error)]
pub enum Response {
#[error("the query was valid, but the primary key queried for did not exist")]
KeyNotFound,
#[error("the query was valid, but there are multiple copies of the key in one database")]
KeyNotUnique,
#[error("the query was invalid: {0}")]
Other(String),
}
#[derive(Debug, thiserror::Error)]
#[error("{inner}")]
pub(crate) struct Wrapper<'a, 'b> {
pipeline: Option<&'b mut Pipeline<'a>>,
#[source]
inner: Error,
}
impl<'a, 'b> Wrapper<'a, 'b> {
pub(crate) fn new(pipeline: Option<&'b mut Pipeline<'a>>, inner: Error) -> Self {
Self { pipeline, inner }
}
pub(crate) fn split(self) -> (Option<&'b mut Pipeline<'a>>, Error) {
(self.pipeline, self.inner)
}
#[allow(clippy::missing_const_for_fn)]
pub(crate) fn take_inner(self) -> Error {
self.inner
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("error response for query {0:?}: {1}")]
ResponseErr(Query, #[source] Response),
#[error("an I/O error occurred: {0}")]
Io(#[from] io::Error),
#[error("failed to decode response length: {0}")]
BadLength(#[from] ParseIntError),
#[error("insufficient bytes in parse buffer")]
Incomplete,
#[error("failed to parse response")]
ParseErr,
#[error("fatal parsing erroring while trying to parse response: {0}")]
ParseFailure(nom::Err<nom::error::Error<Vec<u8>>>),
#[error("failed to parse item from response data: {0}")]
ParseItem(#[source] Box<dyn std::error::Error + Send + Sync>, usize),
#[error("failed to dequeue a query response from the pipeline")]
Dequeue,
#[error("unexpected non-zero data length received for query {0:?}")]
UnexpectedData(Query, usize),
#[error("attempted to extract items after EOR was reached")]
ConsumedResponse,
#[error("premature end of response after {0} bytes: expected {1} bytes")]
ResponseDataUnderrun(usize, usize),
#[error("response data has over run the length indicated in the response preamble")]
ResponseDataOverrun(usize, usize),
#[error("unexpectedly empty response received for query {0:?}")]
EmptyResponse(Query),
}
impl From<Wrapper<'_, '_>> for Error {
fn from(err: Wrapper<'_, '_>) -> Self {
err.inner
}
}
impl From<nom::Err<nom::error::Error<&[u8]>>> for Error {
fn from(err: nom::Err<nom::error::Error<&[u8]>>) -> Self {
match err {
nom::Err::Incomplete(_) => Self::Incomplete,
nom::Err::Error(_) => Self::ParseErr,
nom::Err::Failure(_) => Self::ParseFailure(err.to_owned()),
}
}
}