[wip] implement handling "missing share"

- rework `CacheFile` API
- fix `AppState::{next_chunk, is_done}`
This commit is contained in:
Jörn-Michael Miehe 2025-06-19 10:34:28 +00:00
parent 865566ad0c
commit df055fc4e9
2 changed files with 51 additions and 39 deletions

View file

@ -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<Option<Chunk<'t>>> {
let Some(mut uploading) = self.inner.pop_file(&self.http) else {
fn next_chunk<'t>(&mut self, buffer: &'t mut [u8]) -> sharry::Result<Option<Chunk<'t>>> {
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;
};
match uploading.check_eof() {
Ok(uploading) => {
let bar = self.get_or_create_progressbar(&uploading);
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);
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<bool> {
@ -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)
}

View file

@ -78,23 +78,41 @@ impl CacheFile {
result
}
pub fn start_upload(&mut self, client: &impl Client) -> sharry::Result<bool> {
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<Option<file::Uploading>> {
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<file::Uploading> {
&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<PathBuf> {
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) {