use crate::{
s3::RequestOptions,
s3::{S3, actions, checksum::Checksum},
stream::{db::Db, setup_progress},
};
use anyhow::{Result, anyhow};
use std::{collections::BTreeMap, fmt::Write, path::Path};
pub struct UploadRequest<'a> {
pub s3: &'a S3,
pub key: &'a str,
pub file: &'a Path,
pub file_size: u64,
pub sdb: &'a Db,
pub acl: Option<String>,
pub meta: Option<BTreeMap<String, String>>,
pub quiet: bool,
pub additional_checksum: Option<Checksum>,
pub globals: RequestOptions,
}
pub async fn upload(request: UploadRequest<'_>) -> Result<String> {
let progress_sender = setup_progress(request.quiet, request.file_size).await;
let action = actions::PutObject::new(
request.key,
request.file,
request.acl,
request.meta,
progress_sender,
request.additional_checksum,
request.globals.object_lock.clone(),
);
let response = action.request(request.s3, request.globals).await?;
let etag = &response.get("ETag").ok_or_else(|| anyhow!("no etag"))?;
request.sdb.save_etag(etag)?;
Ok(response.iter().fold(String::new(), |mut output, (k, v)| {
let _ = writeln!(output, "{k}: {v}");
output
}))
}