diff --git a/src/appstate.rs b/src/appstate.rs index 979f03f..e253e53 100644 --- a/src/appstate.rs +++ b/src/appstate.rs @@ -8,19 +8,15 @@ use console::style; use indicatif::{ProgressBar, ProgressStyle}; use log::{debug, warn}; -use crate::file::Chunk; - use super::{ cachefile::CacheFile, cli::Cli, - file::{self, FileTrait}, + file::{self, FileTrait, Chunk}, sharry::{self, Client}, }; pub struct AppState { progress: RefCell>, - buffer: Vec, - http: ureq::Agent, inner: CacheFile, } @@ -41,10 +37,9 @@ fn new_http(timeout: Option) -> ureq::Agent { } impl AppState { - fn new(chunk_size: usize, http: ureq::Agent, inner: CacheFile) -> Self { + fn new(http: ureq::Agent, inner: CacheFile) -> Self { Self { - progress: None.into(), - buffer: vec![0; chunk_size * 1024 * 1024], + progress: RefCell::new(None), http, inner, } @@ -55,11 +50,7 @@ impl AppState { .inspect_err(|e| debug!("could not resume from hash {:?}: {e}", args.get_hash())) .ok()?; - Some(Self::new( - args.chunk_size, - new_http(args.get_timeout()), - inner, - )) + Some(Self::new(new_http(args.get_timeout()), inner)) } pub fn from_args(args: &Cli) -> sharry::Result { @@ -71,11 +62,7 @@ impl AppState { args.get_share_request(), )?; - Ok(Self::new( - args.chunk_size, - http, - CacheFile::from_args(args, share_id), - )) + Ok(Self::new(http, CacheFile::from_args(args, share_id))) } fn get_or_create_progressbar(&self, uploading: &file::Uploading) -> Ref<'_, ProgressBar> { @@ -114,7 +101,7 @@ impl AppState { } } - fn next_chunk(&mut self) -> io::Result> { + fn next_chunk<'t>(&mut self, buffer: &'t mut [u8]) -> io::Result>> { let Some(mut uploading) = self.inner.pop_file(&self.http) else { self.inner .share_notify(&self.http) @@ -122,15 +109,14 @@ impl AppState { return Ok(None); }; - debug!("{uploading:?}"); self.get_or_create_progressbar(&uploading); - let chunk = uploading.read(&mut self.buffer); + let chunk_res = uploading.read(buffer); self.inner.push_file(uploading); - let chunk = chunk?; + let chunk = chunk_res?; debug!("{chunk:?}"); Ok(Some(chunk)) @@ -146,7 +132,7 @@ impl AppState { let bar = self.get_or_create_progressbar(&uploading); bar.set_position(uploading.get_offset()); // BUG in `indicatif` crate? - // `set_position` does not force immediate redraw, so we also call `inc_length` here + // `set_position` does not force an immediate redraw, so we also call `inc_length` here bar.inc_length(0); drop(bar); @@ -161,8 +147,8 @@ impl AppState { self.inner.is_empty() } - pub fn upload_chunk(&mut self) -> sharry::Result { - let Some(chunk) = self.next_chunk()? else { + pub fn upload_chunk(&mut self, buffer: &mut [u8]) -> sharry::Result { + let Some(chunk) = self.next_chunk(buffer)? else { return Ok(true); }; @@ -170,7 +156,7 @@ impl AppState { chunk.get_patch_uri(), self.inner.alias_id(), chunk.get_offset(), - unsafe { chunk.get_data() }, + chunk.get_data(), )?; Ok(self.is_done()) diff --git a/src/file/chunk.rs b/src/file/chunk.rs index 8cf3c49..f93f172 100644 --- a/src/file/chunk.rs +++ b/src/file/chunk.rs @@ -1,25 +1,23 @@ use std::fmt; -pub struct Chunk { - data: *const [u8], +pub struct Chunk<'t> { + data: &'t [u8], patch_uri: String, offset: u64, } -impl fmt::Debug for Chunk { +impl fmt::Debug for Chunk<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Chunk") .field("patch_uri", &self.patch_uri) .field("offset", &self.offset) - .field("data_len", &self.data.len()) + .field("data.len()", &self.data.len()) .finish_non_exhaustive() } } -impl Chunk { - pub fn new(data: &[u8], patch_uri: String, offset: u64) -> Self { - let data: *const [u8] = data as *const [u8]; - +impl<'t> Chunk<'t> { + pub fn new(data: &'t [u8], patch_uri: String, offset: u64) -> Self { Self { data, patch_uri, @@ -27,8 +25,8 @@ impl Chunk { } } - pub unsafe fn get_data(&self) -> &[u8] { - unsafe { &*self.data } + pub fn get_data(&self) -> &[u8] { + self.data } pub fn get_length(&self) -> u64 { diff --git a/src/file/uploading.rs b/src/file/uploading.rs index 2831bcd..dc40d86 100644 --- a/src/file/uploading.rs +++ b/src/file/uploading.rs @@ -52,7 +52,7 @@ impl Uploading { }) } - pub fn read(&mut self, buf: &mut [u8]) -> io::Result { + pub fn read<'t>(&mut self, buf: &'t mut [u8]) -> io::Result> { let mut f = fs::File::open(&self.path)?; f.seek(SeekFrom::Start(self.offset))?; diff --git a/src/main.rs b/src/main.rs index 38b799d..9477a8a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -113,8 +113,10 @@ fn main() { style(state.file_names().join(", ")).magenta(), ); + let mut buffer = vec![0; args.chunk_size * 1024 * 1024]; + loop { - match state.upload_chunk() { + match state.upload_chunk(&mut buffer) { Err(e) => error!("error: {e:?}"), // HACK handle errors better Ok(true) => { info!("all uploads done");