From df055fc4e9619a241c89b4a3362bc7bf2452fbb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn-Michael=20Miehe?= <40151420+ldericher@users.noreply.github.com> Date: Thu, 19 Jun 2025 10:34:28 +0000 Subject: [PATCH] [wip] implement handling "missing share" - rework `CacheFile` API - fix `AppState::{next_chunk, is_done}` --- src/appstate.rs | 48 +++++++++++++++++++++--------------------------- src/cachefile.rs | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/src/appstate.rs b/src/appstate.rs index 68eff53..29edeb9 100644 --- a/src/appstate.rs +++ b/src/appstate.rs @@ -9,7 +9,7 @@ use indicatif::{ProgressBar, ProgressStyle}; use log::{debug, warn}; use crate::{ - cachefile::{CacheFile, FileState}, + cachefile::CacheFile, cli::Cli, file::{self, Chunk, FileTrait}, sharry::{self, Client}, @@ -89,7 +89,7 @@ impl AppState { }) } - fn end_progressbar(&self, f: impl FnOnce(&ProgressBar)) { + fn drop_progressbar(&self, f: impl FnOnce(&ProgressBar)) { let mut slot = self.progress.borrow_mut(); if let Some(bar) = slot.as_ref() { f(bar); @@ -97,8 +97,8 @@ impl AppState { } } - fn next_chunk<'t>(&mut self, buffer: &'t mut [u8]) -> io::Result>> { - let Some(mut uploading) = self.inner.pop_file(&self.http) else { + fn next_chunk<'t>(&mut self, buffer: &'t mut [u8]) -> sharry::Result>> { + let Some(mut uploading) = self.inner.pop_uploading(&self.http)? else { self.inner .share_notify(&self.http) .unwrap_or_else(|e| warn!("Failed to notify the share: {e}")); @@ -109,38 +109,32 @@ impl AppState { self.get_or_create_progressbar(&uploading); - let chunk_res = uploading.read(buffer); - self.inner.push_file(uploading); + let chunk = { + let result = uploading.read(buffer); + self.inner.push_uploading(uploading); - let chunk = chunk_res?; + result? + }; debug!("{chunk:?}"); Ok(Some(chunk)) } fn is_done(&mut self) -> bool { - let Some(uploading) = self.inner.pop_file(&self.http) else { - return true; - }; + if let Some(path) = self.inner.check_eof() { + debug!("Finished {:?}!", path.display()); + self.drop_progressbar(ProgressBar::finish); + } else if let Some(uploading) = self.inner.peek_uploading() { + let bar = self.get_or_create_progressbar(uploading); + bar.set_position(uploading.get_offset()); + // BUG in `indicatif` crate? + // `set_position` does not force an immediate redraw, so we also call `inc_length` here + bar.inc_length(0); - match uploading.check_eof() { - Ok(uploading) => { - let bar = self.get_or_create_progressbar(&uploading); - bar.set_position(uploading.get_offset()); - // BUG in `indicatif` crate? - // `set_position` does not force an immediate redraw, so we also call `inc_length` here - bar.inc_length(0); - drop(bar); - - self.inner.push_file(uploading); - } - Err(path) => { - debug!("Finished {:?}!", path.display()); - self.end_progressbar(|pb| pb.finish()); - } + return false; } - self.inner.is_empty() + self.inner.queue_empty() } pub fn upload_chunk(&mut self, buffer: &mut [u8]) -> sharry::Result { @@ -183,7 +177,7 @@ impl AppState { let checked = uploading.abort(); self.inner.requeue_file(checked); - self.end_progressbar(|pb| pb.abandon()); + self.drop_progressbar(|pb| pb.abandon()); Some(self) } diff --git a/src/cachefile.rs b/src/cachefile.rs index 022244e..12d3478 100644 --- a/src/cachefile.rs +++ b/src/cachefile.rs @@ -78,23 +78,41 @@ impl CacheFile { result } - pub fn start_upload(&mut self, client: &impl Client) -> sharry::Result { - if self.uploading.is_some() { - return Ok(true); - } + pub fn queue_empty(&self) -> bool { + self.files.is_empty() + } - if let Some(chk) = self.files.pop_front() { - self.uploading = - Some(chk.start_upload(client, &self.uri, &self.alias_id, &self.share_id)?); - - Ok(true) + pub fn pop_uploading( + &mut self, + client: &impl Client, + ) -> sharry::Result> { + if let Some(upl) = self.uploading.take() { + Ok(Some(upl)) + } else if let Some(chk) = self.files.pop_front() { + let upl = chk.start_upload(client, &self.uri, &self.alias_id, &self.share_id)?; + Ok(Some(upl)) } else { - Ok(false) + Ok(None) } } - pub fn uploading(&mut self) -> &mut Option { - &mut self.uploading + pub fn push_uploading(&mut self, uploading: file::Uploading) { + self.uploading.replace(uploading); + } + + pub fn peek_uploading(&self) -> Option<&file::Uploading> { + self.uploading.as_ref() + } + + pub fn check_eof(&mut self) -> Option { + if let Some(upl) = self.uploading.take() { + match upl.check_eof() { + Ok(upl) => self.push_uploading(upl), + Err(p) => return Some(p), + } + } + + None } pub fn abort_upload(&mut self) {