2
0
Fork 0
mirror of https://git.asonix.dog/asonix/pict-rs synced 2024-12-22 19:31:35 +00:00
pict-rs/src/store.rs

246 lines
6.8 KiB
Rust
Raw Permalink Normal View History

2021-10-23 04:48:56 +00:00
use actix_web::web::Bytes;
2023-08-23 16:59:42 +00:00
use futures_core::Stream;
use std::{fmt::Debug, sync::Arc};
2021-10-23 04:48:56 +00:00
use crate::{bytes_stream::BytesStream, error_code::ErrorCode, stream::LocalBoxStream};
2023-09-02 01:50:10 +00:00
2021-10-23 04:48:56 +00:00
pub(crate) mod file_store;
pub(crate) mod object_store;
2021-10-23 04:48:56 +00:00
#[derive(Debug, thiserror::Error)]
pub(crate) enum StoreError {
#[error("Error in file store")]
FileStore(#[source] crate::store::file_store::FileError),
#[error("Error in object store")]
ObjectStore(#[source] crate::store::object_store::ObjectError),
#[error("Error in DB")]
Repo(#[from] crate::repo::RepoError),
#[error("Error in 0.4 DB")]
Repo04(#[from] crate::repo_04::RepoError),
#[error("Error reading bytes stream")]
ReadStream(#[source] std::io::Error),
#[error("Requested file is not found")]
FileNotFound(#[source] std::io::Error),
#[error("Requested object is not found")]
ObjectNotFound(#[source] crate::store::object_store::ObjectError),
}
impl StoreError {
2023-09-02 01:50:10 +00:00
pub(crate) const fn error_code(&self) -> ErrorCode {
match self {
Self::FileStore(e) => e.error_code(),
Self::ObjectStore(e) => e.error_code(),
Self::Repo(e) => e.error_code(),
Self::ReadStream(_) => ErrorCode::IO_ERROR,
2023-09-02 01:50:10 +00:00
Self::Repo04(_) => ErrorCode::OLD_REPO_ERROR,
Self::FileNotFound(_) | Self::ObjectNotFound(_) => ErrorCode::NOT_FOUND,
}
}
2023-09-05 02:51:27 +00:00
pub(crate) const fn is_not_found(&self) -> bool {
matches!(self, Self::FileNotFound(_)) || matches!(self, Self::ObjectNotFound(_))
}
2023-09-05 02:51:27 +00:00
pub(crate) const fn is_disconnected(&self) -> bool {
match self {
Self::Repo(e) => e.is_disconnected(),
_ => false,
}
}
}
impl From<crate::store::file_store::FileError> for StoreError {
fn from(value: crate::store::file_store::FileError) -> Self {
match value {
crate::store::file_store::FileError::Io(e)
if e.kind() == std::io::ErrorKind::NotFound =>
{
Self::FileNotFound(e)
}
e => Self::FileStore(e),
}
}
}
impl From<crate::store::object_store::ObjectError> for StoreError {
fn from(value: crate::store::object_store::ObjectError) -> Self {
match value {
e @ crate::store::object_store::ObjectError::Request(
::object_store::Error::NotFound { .. },
) => Self::ObjectNotFound(e),
e => Self::ObjectStore(e),
}
}
}
2022-09-24 19:18:49 +00:00
pub(crate) trait Store: Clone + Debug {
2023-07-07 17:05:42 +00:00
async fn health_check(&self) -> Result<(), StoreError>;
async fn save_stream<S>(
&self,
stream: S,
content_type: mime::Mime,
2024-02-28 02:41:25 +00:00
extension: Option<&str>,
) -> Result<Arc<str>, StoreError>
2021-10-23 04:48:56 +00:00
where
2024-02-23 00:05:04 +00:00
S: Stream<Item = std::io::Result<Bytes>>;
2021-10-23 04:48:56 +00:00
fn public_url(&self, _: &Arc<str>) -> Option<url::Url>;
2021-10-23 04:48:56 +00:00
async fn to_stream(
&self,
identifier: &Arc<str>,
2021-10-23 04:48:56 +00:00
from_start: Option<u64>,
len: Option<u64>,
) -> Result<LocalBoxStream<'static, std::io::Result<Bytes>>, StoreError>;
2021-10-23 04:48:56 +00:00
async fn to_bytes(
&self,
identifier: &Arc<str>,
from_start: Option<u64>,
len: Option<u64>,
) -> Result<BytesStream, StoreError> {
2024-02-22 22:10:34 +00:00
let stream = self.to_stream(identifier, from_start, len).await?;
2024-02-22 22:10:34 +00:00
BytesStream::try_from_stream(stream)
.await
.map_err(StoreError::ReadStream)
}
async fn len(&self, identifier: &Arc<str>) -> Result<u64, StoreError>;
2021-10-23 04:48:56 +00:00
async fn remove(&self, identifier: &Arc<str>) -> Result<(), StoreError>;
2021-10-23 04:48:56 +00:00
}
impl<T> Store for actix_web::web::Data<T>
where
T: Store,
{
2023-07-07 17:05:42 +00:00
async fn health_check(&self) -> Result<(), StoreError> {
T::health_check(self).await
}
async fn save_stream<S>(
&self,
stream: S,
content_type: mime::Mime,
2024-02-28 02:41:25 +00:00
extension: Option<&str>,
) -> Result<Arc<str>, StoreError>
2022-09-24 22:18:53 +00:00
where
2024-02-23 00:05:04 +00:00
S: Stream<Item = std::io::Result<Bytes>>,
2022-09-24 22:18:53 +00:00
{
2024-02-28 02:41:25 +00:00
T::save_stream(self, stream, content_type, extension).await
2022-09-24 22:18:53 +00:00
}
fn public_url(&self, identifier: &Arc<str>) -> Option<url::Url> {
2023-07-14 20:23:07 +00:00
T::public_url(self, identifier)
}
async fn to_stream(
&self,
identifier: &Arc<str>,
from_start: Option<u64>,
len: Option<u64>,
) -> Result<LocalBoxStream<'static, std::io::Result<Bytes>>, StoreError> {
2022-09-11 15:04:37 +00:00
T::to_stream(self, identifier, from_start, len).await
}
async fn len(&self, identifier: &Arc<str>) -> Result<u64, StoreError> {
2022-09-11 15:04:37 +00:00
T::len(self, identifier).await
}
async fn remove(&self, identifier: &Arc<str>) -> Result<(), StoreError> {
2022-09-11 15:04:37 +00:00
T::remove(self, identifier).await
}
}
impl<T> Store for Arc<T>
where
T: Store,
{
2023-07-07 17:05:42 +00:00
async fn health_check(&self) -> Result<(), StoreError> {
T::health_check(self).await
}
async fn save_stream<S>(
&self,
stream: S,
content_type: mime::Mime,
2024-02-28 02:41:25 +00:00
extension: Option<&str>,
) -> Result<Arc<str>, StoreError>
2022-09-24 22:18:53 +00:00
where
2024-02-23 00:05:04 +00:00
S: Stream<Item = std::io::Result<Bytes>>,
2022-09-24 22:18:53 +00:00
{
2024-02-28 02:41:25 +00:00
T::save_stream(self, stream, content_type, extension).await
2022-09-24 22:18:53 +00:00
}
fn public_url(&self, identifier: &Arc<str>) -> Option<url::Url> {
2023-07-14 20:23:07 +00:00
T::public_url(self, identifier)
}
async fn to_stream(
&self,
identifier: &Arc<str>,
from_start: Option<u64>,
len: Option<u64>,
) -> Result<LocalBoxStream<'static, std::io::Result<Bytes>>, StoreError> {
T::to_stream(self, identifier, from_start, len).await
}
async fn len(&self, identifier: &Arc<str>) -> Result<u64, StoreError> {
T::len(self, identifier).await
}
async fn remove(&self, identifier: &Arc<str>) -> Result<(), StoreError> {
T::remove(self, identifier).await
}
}
impl<'a, T> Store for &'a T
where
T: Store,
{
async fn health_check(&self) -> Result<(), StoreError> {
T::health_check(self).await
}
async fn save_stream<S>(
&self,
stream: S,
content_type: mime::Mime,
2024-02-28 02:41:25 +00:00
extension: Option<&str>,
) -> Result<Arc<str>, StoreError>
where
2024-02-23 00:05:04 +00:00
S: Stream<Item = std::io::Result<Bytes>>,
{
2024-02-28 02:41:25 +00:00
T::save_stream(self, stream, content_type, extension).await
}
fn public_url(&self, identifier: &Arc<str>) -> Option<url::Url> {
T::public_url(self, identifier)
}
async fn to_stream(
&self,
identifier: &Arc<str>,
from_start: Option<u64>,
len: Option<u64>,
) -> Result<LocalBoxStream<'static, std::io::Result<Bytes>>, StoreError> {
T::to_stream(self, identifier, from_start, len).await
}
async fn len(&self, identifier: &Arc<str>) -> Result<u64, StoreError> {
T::len(self, identifier).await
}
async fn remove(&self, identifier: &Arc<str>) -> Result<(), StoreError> {
T::remove(self, identifier).await
}
}