use std::sync::Arc;
use super::target::{Target, TargetError};
use crate::backend::s3::{S3, client_for};
use crate::config::{S3Settings, StorageError};
#[derive(Debug)]
pub struct S3Target {
s3: Arc<S3>,
}
impl S3Target {
pub fn connect(settings: &S3Settings, table: &str) -> Result<S3Target, StorageError> {
Ok(S3Target {
s3: client_for(settings, table)?,
})
}
#[cfg(all(test, feature = "backend-tests"))]
pub(crate) fn client(&self) -> &Arc<S3> {
&self.s3
}
}
impl Target for S3Target {
fn put_new(&self, path: &str, bytes: &[u8]) -> Result<(), TargetError> {
match self.s3.put_new(path, bytes.to_vec()) {
Ok(true) => Ok(()),
Ok(false) => Err(TargetError::Exists),
Err(e) => Err(TargetError::Io(e.to_string())),
}
}
fn list(&self, dir: &str) -> Result<Vec<String>, TargetError> {
let names = self
.s3
.names_under(dir)
.map_err(|e| TargetError::Io(e.to_string()))?;
Ok(names
.into_iter()
.map(|n| n.trim_end_matches('/').to_owned())
.collect())
}
fn remove(&self, path: &str) -> Result<(), TargetError> {
self.s3
.remove_named(path)
.map_err(|e| TargetError::Io(e.to_string()))
}
fn describe(&self) -> String {
self.s3.url()
}
}