use async_trait::async_trait;
use auto_impl::auto_impl;
use etwin_core::declare_new_uuid;
use etwin_core::types::AnyError;
declare_new_uuid! {
pub struct BufferId(Uuid);
pub type ParseError = BufferIdParseError;
const SQL_NAME = "buffer_id";
}
#[derive(Debug, thiserror::Error)]
pub enum CreateBufferError {
#[error("Failed to allocate a buffer of size {:?} because it is too large", .0)]
MaxSize(u32),
#[error(transparent)]
Other(#[from] AnyError),
}
impl CreateBufferError {
pub fn other<E>(e: E) -> Self
where
E: ::std::error::Error + Send + Sync + 'static,
{
CreateBufferError::Other(Box::new(e))
}
}
#[derive(Debug, thiserror::Error)]
pub enum DeleteBufferError {
#[error("Failed to delete: buffer not found for id {:?}", .0)]
NotFound(BufferId),
#[error(transparent)]
Other(#[from] AnyError),
}
#[derive(Debug, thiserror::Error)]
pub enum WriteBytesError {
#[error("Failed to write: buffer not found for id {:?}", .0)]
NotFound(BufferId),
#[error("Failed to write: input bytes too large")]
MaxSize,
#[error("Write past end of buffer")]
BufferOverflow,
#[error(transparent)]
Other(#[from] AnyError),
}
impl WriteBytesError {
pub fn other<E>(e: E) -> Self
where
E: ::std::error::Error + Send + Sync + 'static,
{
WriteBytesError::Other(Box::new(e))
}
}
#[derive(Debug, thiserror::Error)]
pub enum ReadStreamError {
#[error("Failed to read: buffer not found for id {:?}", .0)]
NotFound(BufferId),
#[error(transparent)]
Other(#[from] AnyError),
}
#[async_trait]
#[auto_impl(&, Arc)]
pub trait BufferStore: Send + Sync {
async fn create_buffer(&self, size: u32) -> Result<BufferId, CreateBufferError>;
async fn delete_buffer(&self, buffer_id: BufferId) -> Result<(), DeleteBufferError>;
async fn delete_buffer_if_exists(&self, buffer_id: BufferId) -> Result<(), AnyError>;
async fn write_bytes(&self, buffer_id: BufferId, offset: u32, bytes: &[u8]) -> Result<(), WriteBytesError>;
async fn read_stream(&self, buffer_id: BufferId) -> Result<Vec<u8>, ReadStreamError>;
}