diff --git a/console_backend/src/bin/fileio.rs b/console_backend/src/bin/fileio.rs index afb03a9c8..f20ad6911 100644 --- a/console_backend/src/bin/fileio.rs +++ b/console_backend/src/bin/fileio.rs @@ -74,9 +74,16 @@ fn main() -> Result<()> { scope(|s| { s.spawn(|_| run(rdr)); let mut fileio = Fileio::new(link, sender); - let data = fs::File::open(source)?; - fileio.overwrite(dest, data)?; - eprintln!("file written successfully."); + let file = fs::File::open(source)?; + let size = file.metadata()?.len() as usize; + let mut bytes_written = 0; + eprint!("\rWriting 0.0%..."); + fileio.overwrite_with_progress(dest, file, |n| { + bytes_written += n; + let progress = (bytes_written as f64) / (size as f64) * 100.0; + eprint!("\rWriting {:.2}%...", progress); + })?; + eprintln!("\nFile written successfully."); done_tx.send(true).unwrap(); Result::Ok(()) }) @@ -122,7 +129,7 @@ fn main() -> Result<()> { s.spawn(|_| run(rdr)); let fileio = Fileio::new(link, sender); fileio.remove(path)?; - eprintln!("file deleted."); + eprintln!("File deleted."); done_tx.send(true).unwrap(); Result::Ok(()) }) diff --git a/console_backend/src/fileio.rs b/console_backend/src/fileio.rs index 958428f15..93db7b06f 100644 --- a/console_backend/src/fileio.rs +++ b/console_backend/src/fileio.rs @@ -155,6 +155,21 @@ impl<'a> Fileio<'a> { /// This operation is NOT atomic. If the write fails and `filename` existed, it is gone forever. /// For more context see: https://github.com/swift-nav/console_pp/pull/72#discussion_r654751414 pub fn overwrite(&mut self, filename: String, data: impl Read) -> Result<()> { + self.overwrite_with_progress(filename, data, |_| ()) + } + + /// Deletes `filename` on the remote device (if it exists) and writes the contents of `data` to the file. + /// This operation is NOT atomic. If the write fails and `filename` existed, it is gone forever. + /// For more context see: https://github.com/swift-nav/console_pp/pull/72#discussion_r654751414 + pub fn overwrite_with_progress<'b, F>( + &mut self, + filename: String, + data: impl Read, + mut on_progress: F, + ) -> Result<()> + where + F: FnMut(usize) + 'b, + { self.remove(filename.clone())?; let mut data = BufReader::new(data); @@ -166,14 +181,22 @@ impl<'a> Fileio<'a> { if bytes_read == 0 { break; } - state = self.write_slice(state, buf)?; + state = self.write_slice(state, buf, &mut on_progress)?; data.consume(bytes_read); } Ok(()) } - fn write_slice(&mut self, mut state: WriteState, data: &[u8]) -> Result { + fn write_slice<'b, F>( + &mut self, + mut state: WriteState, + data: &[u8], + on_progress: &mut F, + ) -> Result + where + F: FnMut(usize) + 'b, + { let config = self.fetch_config(); let (req_tx, req_rx) = channel::unbounded(); @@ -234,9 +257,11 @@ impl<'a> Fileio<'a> { }, recv(res_rx) -> msg => { let msg = msg?; - if pending.remove(&msg.sequence).is_none() { - continue - } + let req = match pending.remove(&msg.sequence) { + Some((_, req)) => req, + _ => continue, + }; + on_progress(req.end_offset - req.offset); open_requests.fetch_sub(1); if last_sent && open_requests.load() == 0 { break;