use super::{S3PutRequest, StorageAdaptor, StoredObject};
use crate::error::TrazaeoResult;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DeterministicS3StorageAdaptor {
pub bucket: String,
pub base_prefix: Option<String>,
}
impl DeterministicS3StorageAdaptor {
pub fn new(bucket: &str, base_prefix: Option<&str>) -> Self {
Self {
bucket: bucket.to_string(),
base_prefix: base_prefix.map(str::to_string),
}
}
pub fn build_key(&self, object_name: &str) -> String {
let prefix = self.base_prefix.as_deref().unwrap_or("").trim_matches('/');
if prefix.is_empty() {
object_name.trim_start_matches('/').to_string()
} else {
format!("{prefix}/{}", object_name.trim_start_matches('/'))
}
}
pub fn build_uri(&self, key: &str) -> String {
format!("s3://{}/{}", self.bucket, key.trim_start_matches('/'))
}
}
impl StorageAdaptor for DeterministicS3StorageAdaptor {
fn put_bytes(&self, request: &S3PutRequest) -> TrazaeoResult<StoredObject> {
let hash = blake3::hash(&request.bytes);
Ok(StoredObject {
key: request.key.clone(),
uri: self.build_uri(&request.key),
content_hash: hex::encode(hash.as_bytes()),
byte_length: request.bytes.len(),
content_type: request.content_type.clone(),
})
}
}