#[cfg(feature = "cloud-s3")]
pub mod s3_writer;
#[cfg(feature = "cloud-s3")]
pub mod s3_reader;
#[cfg(feature = "cloud-gcs")]
pub mod gcs_writer;
#[cfg(feature = "cloud-http")]
pub mod http_writer;
pub mod replicate;
#[cfg(feature = "cloud-s3")]
pub use s3_writer::S3ExcelWriter;
#[cfg(feature = "cloud-s3")]
pub use s3_reader::S3ExcelReader;
#[cfg(feature = "cloud-gcs")]
pub use gcs_writer::GCSExcelWriter;
#[cfg(feature = "cloud-http")]
pub use http_writer::HttpExcelWriter;
use crate::error::Result;
use std::io::Write;
pub trait CloudStorage: Write + Send {
fn start_upload(&mut self) -> impl std::future::Future<Output = Result<String>> + Send;
fn upload_part(
&mut self,
upload_id: &str,
part_number: u32,
data: &[u8],
) -> impl std::future::Future<Output = Result<String>> + Send;
fn complete_upload(
&mut self,
upload_id: &str,
parts: Vec<(u32, String)>,
) -> impl std::future::Future<Output = Result<()>> + Send;
fn abort_upload(
&mut self,
upload_id: &str,
) -> impl std::future::Future<Output = Result<()>> + Send;
}
pub struct CloudBuffer {
buffer: Vec<u8>,
part_size: usize,
uploaded_parts: Vec<(u32, String)>,
current_part_number: u32,
}
impl CloudBuffer {
pub fn new(part_size: usize) -> Self {
Self {
buffer: Vec::with_capacity(part_size),
part_size,
uploaded_parts: Vec::new(),
current_part_number: 1,
}
}
pub fn is_full(&self) -> bool {
self.buffer.len() >= self.part_size
}
pub fn data(&self) -> &[u8] {
&self.buffer
}
pub fn clear(&mut self) {
self.buffer.clear();
}
pub fn add_uploaded_part(&mut self, etag: String) {
self.uploaded_parts.push((self.current_part_number, etag));
self.current_part_number += 1;
}
pub fn uploaded_parts(&self) -> &[(u32, String)] {
&self.uploaded_parts
}
pub fn current_part_number(&self) -> u32 {
self.current_part_number
}
}
impl Write for CloudBuffer {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buffer.extend_from_slice(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}