use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;
use backoff::future::retry;
use backoff::ExponentialBackoff;
use super::{LFSObject, Storage, StorageKey, StorageStream};
pub struct Backend<S> {
storage: Arc<S>,
}
impl<S> Backend<S> {
pub fn new(storage: S) -> Self {
Backend {
storage: Arc::new(storage),
}
}
}
#[async_trait]
impl<S> Storage for Backend<S>
where
S: Storage + Send + Sync + 'static,
S::Error: 'static,
{
type Error = S::Error;
async fn get(
&self,
key: &StorageKey,
) -> Result<Option<LFSObject>, Self::Error> {
self.storage.get(key).await
}
async fn put(
&self,
key: StorageKey,
value: LFSObject,
) -> Result<(), Self::Error> {
self.storage.put(key, value).await
}
async fn size(&self, key: &StorageKey) -> Result<Option<u64>, Self::Error> {
retry(ExponentialBackoff::default(), || async {
Ok(self.storage.size(key).await?)
})
.await
}
async fn delete(&self, key: &StorageKey) -> Result<(), Self::Error> {
retry(ExponentialBackoff::default(), || async {
Ok(self.storage.delete(key).await?)
})
.await
}
fn list(&self) -> StorageStream<(StorageKey, u64), Self::Error> {
self.storage.list()
}
async fn total_size(&self) -> Option<u64> {
self.storage.total_size().await
}
async fn max_size(&self) -> Option<u64> {
self.storage.max_size().await
}
fn public_url(&self, key: &StorageKey) -> Option<String> {
self.storage.public_url(key)
}
async fn upload_url(
&self,
key: &StorageKey,
expires_in: Duration,
) -> Option<String> {
self.storage.upload_url(key, expires_in).await
}
}