use super::archive_private::{PrivateArchive, PrivateArchiveDataMap};
use super::{DownloadError, UploadError, bulk_upload_internal, file_upload_internal};
use crate::client::PutError;
use crate::client::data_types::chunk::DataMapChunk;
use crate::client::payment::{BulkPaymentOption, PaymentOption};
use crate::client::quote::add_costs;
use crate::{AttoTokens, Client};
use std::path::PathBuf;
impl Client {
pub async fn file_download(
&self,
data_map: &DataMapChunk,
to_dest: PathBuf,
) -> Result<(), DownloadError> {
info!("Downloading private file to {to_dest:?}");
if let Some(parent) = to_dest.parent() {
tokio::fs::create_dir_all(parent).await?;
}
let datamap = self.restore_data_map_from_chunk(data_map).await?;
self.stream_download_from_datamap(datamap, &to_dest)?;
debug!("Successfully downloaded private file to {to_dest:?}");
Ok(())
}
pub async fn dir_download(
&self,
archive_access: &PrivateArchiveDataMap,
to_dest: PathBuf,
) -> Result<(), DownloadError> {
let archive = self.archive_get(archive_access).await?;
for (path, addr, _meta) in archive.iter() {
self.file_download(addr, to_dest.join(path)).await?;
}
debug!("Downloaded directory to {to_dest:?}");
Ok(())
}
pub async fn dir_content_upload(
&self,
dir_path: PathBuf,
payment_option: BulkPaymentOption,
) -> Result<(AttoTokens, PrivateArchive), UploadError> {
bulk_upload_internal(self, dir_path, payment_option, false, |results| {
let mut archive = PrivateArchive::new();
for (path, datamap, metadata) in results {
archive.add_file(path, datamap, metadata);
}
archive
})
.await
}
pub async fn dir_upload(
&self,
dir_path: PathBuf,
wallet: &ant_evm::EvmWallet,
) -> Result<(AttoTokens, PrivateArchiveDataMap), UploadError> {
let (cost1, archive) = self
.dir_content_upload(dir_path, BulkPaymentOption::Wallet(wallet.clone()))
.await?;
let (cost2, archive_addr) = self
.archive_put(&archive, PaymentOption::Wallet(wallet.clone()))
.await?;
let total_cost = add_costs(cost1, cost2).map_err(PutError::from)?;
Ok((total_cost, archive_addr))
}
pub async fn file_content_upload(
&self,
path: PathBuf,
payment_option: BulkPaymentOption,
) -> Result<(AttoTokens, DataMapChunk), UploadError> {
file_upload_internal(self, path, payment_option, false).await
}
}
#[cfg(test)]
mod tests {
use crate::self_encryption::MAX_CHUNK_SIZE;
#[test]
fn test_chunk_estimation_ceiling_division() {
let small_size: usize = 500 * 1024; let estimated = std::cmp::max(3, small_size.div_ceil(MAX_CHUNK_SIZE));
assert!(
estimated >= 3,
"Small files should estimate at least 3 chunks"
);
let medium_size: usize = (MAX_CHUNK_SIZE * 3) / 2; let estimated = std::cmp::max(3, medium_size.div_ceil(MAX_CHUNK_SIZE));
assert!(
estimated >= 3,
"1.5MB file should estimate at least 3 chunks (self-encryption minimum)"
);
let exact_size: usize = MAX_CHUNK_SIZE * 5;
let estimated = exact_size.div_ceil(MAX_CHUNK_SIZE);
assert_eq!(estimated, 5, "Exact multiples should estimate correctly");
let zero_estimated = std::cmp::max(3, 0_usize.div_ceil(MAX_CHUNK_SIZE));
assert_eq!(
zero_estimated, 3,
"Empty files should estimate 3 chunks minimum"
);
}
}