indexkv 0.8.0

A performance-focused, persistent, async, key-value store
Documentation
use std::{error, fmt};

use crate::Key;

#[derive(Debug, thiserror::Error)]
pub enum Error<K: Key> {
	#[error("I/O error")]
	IO(#[from] std::io::Error),
	#[error("Failed to join blocking task:  {0}")]
	Join(#[from] tokio::task::JoinError),
	#[error("Codec error:  {0}")]
	Codec(#[from] bitcode::Error),
	#[error("key {0} not found")]
	NotFound(K),
	#[error("missing value")]
	MissingValue,
}

/// Wraps both [indexkv errors](Error) and generic errors that could end up in the stream passed to
/// [Store::write](crate::Store::write)
#[derive(Debug)]
pub enum StreamError<E: error::Error, K: Key> {
	Internal(Error<K>),
	Caller(E),
}

impl<E: error::Error, K: Key> fmt::Display for StreamError<E, K> {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
		match self {
			Self::Internal(e) => write!(f, "indexkv error writing stream: {e}"),
			Self::Caller(e) => write!(f, "external error writing stream: {e}"),
		}
	}
}

impl<E: error::Error + 'static, K: Key + 'static> error::Error for StreamError<E, K> {
	fn source(&self) -> Option<&(dyn error::Error + 'static)> {
		match self {
			Self::Internal(e) => Some(e),
			Self::Caller(e) => Some(e),
		}
	}
}

impl<E: error::Error, K: Key, T> From<T> for StreamError<E, K>
where
	Error<K>: From<T>,
{
	fn from(inner: T) -> Self {
		Self::Internal(Error::from(inner))
	}
}

impl<E: error::Error, K: Key> StreamError<E, K> {
	pub(crate) fn from_external(inner: E) -> Self {
		Self::Caller(inner)
	}
}