#[cfg(feature = "backend-d1")]
pub mod d1;
pub mod http;
pub mod local;
#[cfg(feature = "backend-s3")]
pub mod s3;
#[cfg(feature = "backend-turso")]
pub mod turso;
use std::fmt;
use std::path::Path;
#[derive(Debug)]
pub enum BackendError {
Transport(String),
Auth(String),
NotFound(String),
PreconditionFailed(String),
Config(String),
Internal(String),
}
impl fmt::Display for BackendError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Transport(msg) => write!(f, "backend transport error: {msg}"),
Self::Auth(msg) => write!(f, "backend auth error: {msg}"),
Self::NotFound(msg) => write!(f, "backend not found: {msg}"),
Self::PreconditionFailed(msg) => write!(f, "backend precondition failed: {msg}"),
Self::Config(msg) => write!(f, "backend config error: {msg}"),
Self::Internal(msg) => write!(f, "backend internal error: {msg}"),
}
}
}
impl std::error::Error for BackendError {}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BackendObjectVersion {
pub token: String,
}
impl BackendObjectVersion {
pub fn new(token: impl Into<String>) -> Self {
Self {
token: token.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ConditionalPut {
IfAbsent,
IfVersion(BackendObjectVersion),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ConditionalDelete {
IfVersion(BackendObjectVersion),
}
pub trait RemoteBackend: Send + Sync {
fn name(&self) -> &str;
fn download(&self, remote_key: &str, local_path: &Path) -> Result<bool, BackendError>;
fn upload(&self, local_path: &Path, remote_key: &str) -> Result<(), BackendError>;
fn exists(&self, remote_key: &str) -> Result<bool, BackendError>;
fn delete(&self, remote_key: &str) -> Result<(), BackendError>;
fn list(&self, prefix: &str) -> Result<Vec<String>, BackendError>;
}
pub trait AtomicRemoteBackend: RemoteBackend {
fn object_version(
&self,
remote_key: &str,
) -> Result<Option<BackendObjectVersion>, BackendError>;
fn upload_conditional(
&self,
local_path: &Path,
remote_key: &str,
condition: ConditionalPut,
) -> Result<BackendObjectVersion, BackendError>;
fn delete_conditional(
&self,
remote_key: &str,
condition: ConditionalDelete,
) -> Result<(), BackendError>;
}
#[cfg(feature = "backend-d1")]
pub use d1::{D1Backend, D1Config};
pub use http::{AtomicHttpBackend, HttpBackend, HttpBackendConfig};
pub use local::LocalBackend;
#[cfg(feature = "backend-s3")]
pub use s3::{S3Backend, S3Config};
#[cfg(feature = "backend-turso")]
pub use turso::{TursoBackend, TursoConfig};