diff --git a/src/appstate.rs b/src/appstate.rs index e253e53..8ce7180 100644 --- a/src/appstate.rs +++ b/src/appstate.rs @@ -11,7 +11,7 @@ use log::{debug, warn}; use super::{ cachefile::CacheFile, cli::Cli, - file::{self, FileTrait, Chunk}, + file::{self, Chunk, FileTrait}, sharry::{self, Client}, }; @@ -162,6 +162,18 @@ impl AppState { Ok(self.is_done()) } + pub fn rewind(mut self) -> Option { + let Some(uploading) = self.inner.pop_file(&self.http) else { + warn!("rewind called on empty queue"); + return None; + }; + + let uploading = uploading.rewind()?; + self.inner.push_file(uploading); + + Some(self) + } + pub fn file_names(&self) -> Vec<&str> { self.inner.file_names() } diff --git a/src/file/uploading.rs b/src/file/uploading.rs index dc40d86..0b2118f 100644 --- a/src/file/uploading.rs +++ b/src/file/uploading.rs @@ -4,6 +4,7 @@ use std::{ path::PathBuf, }; +use log::warn; use serde::{Deserialize, Serialize}; use super::{Chunk, FileTrait}; @@ -45,11 +46,17 @@ impl Uploading { } pub fn rewind(self) -> Option { - self.last_offset.map(|last_offset| Self { - last_offset: None, - offset: last_offset, - ..self - }) + match self.last_offset { + Some(last_offset) => Some(Self { + last_offset: None, + offset: last_offset, + ..self + }), + None => { + warn!("attempted to rewind twice"); + None + } + } } pub fn read<'t>(&mut self, buf: &'t mut [u8]) -> io::Result> { diff --git a/src/main.rs b/src/main.rs index 9477a8a..dcfa946 100644 --- a/src/main.rs +++ b/src/main.rs @@ -117,7 +117,17 @@ fn main() { loop { match state.upload_chunk(&mut buffer) { - Err(e) => error!("error: {e:?}"), // HACK handle errors better + Err(e) => { + // HACK handle errors better + error!("error: {e:?}"); + + if let Some(s) = state.rewind() { + state = s; + } else { + eprintln!("{} Failed to retry chunk!", style("Error:").red().bold()); + process::exit(1); + }; + } Ok(true) => { info!("all uploads done"); state.clear().unwrap_or_else(|e| {