use crate::callback::{c_callback, with_libstorage_lock, CallbackFuture};
use crate::error::{Result, StorageError};
use crate::ffi::{
storage_upload_cancel, storage_upload_finalize, storage_upload_init, string_to_c_string,
};
use crate::node::lifecycle::StorageNode;
use crate::upload::types::UploadOptions;
pub async fn upload_init(node: &StorageNode, options: &UploadOptions) -> Result<String> {
options.validate()?;
let future = CallbackFuture::new();
let context_ptr = future.context_ptr();
let filepath_str = options
.filepath
.as_ref()
.and_then(|p| p.to_str())
.unwrap_or("");
let chunk_size = options.chunk_size.unwrap_or(64 * 1024);
let result = with_libstorage_lock(|| unsafe {
node.with_ctx(|ctx| {
let c_filepath = string_to_c_string(filepath_str);
storage_upload_init(
ctx as *mut _,
c_filepath.as_ptr(),
chunk_size,
Some(c_callback),
context_ptr.as_ptr(),
)
})
});
if result != 0 {
return Err(StorageError::upload_error("Failed to initialize upload"));
}
let session_id = future.await?;
Ok(session_id)
}
pub async fn upload_finalize(node: &StorageNode, session_id: &str) -> Result<String> {
if session_id.is_empty() {
return Err(StorageError::invalid_parameter(
"session_id",
"Session ID cannot be empty",
));
}
let future = CallbackFuture::new();
let context_ptr = future.context_ptr();
let result = with_libstorage_lock(|| unsafe {
node.with_ctx(|ctx| {
let c_session_id = string_to_c_string(session_id);
storage_upload_finalize(
ctx as *mut _,
c_session_id.as_ptr(),
Some(c_callback),
context_ptr.as_ptr(),
)
})
});
if result != 0 {
return Err(StorageError::upload_error("Failed to finalize upload"));
}
let cid = future.await?;
Ok(cid)
}
pub async fn upload_cancel(node: &StorageNode, session_id: &str) -> Result<()> {
if session_id.is_empty() {
return Err(StorageError::invalid_parameter(
"session_id",
"Session ID cannot be empty",
));
}
let future = CallbackFuture::new();
let context_ptr = future.context_ptr();
let result = with_libstorage_lock(|| unsafe {
node.with_ctx(|ctx| {
let c_session_id = string_to_c_string(session_id);
storage_upload_cancel(
ctx as *mut _,
c_session_id.as_ptr(),
Some(c_callback),
context_ptr.as_ptr(),
)
})
});
if result != 0 {
return Err(StorageError::upload_error("Failed to cancel upload"));
}
future.await?;
Ok(())
}