feat: store backup sizes in metadata file

This commit is contained in:
Jef Roosens 2023-07-03 11:54:11 +02:00
parent a4a03ca4c5
commit c5193f0f3c
Signed by: Jef Roosens
GPG key ID: B75D4F293C7052DB
4 changed files with 71 additions and 9 deletions

43
src/backup/io_ext.rs Normal file
View file

@ -0,0 +1,43 @@
use std::io::{self, Write};
/// Wrapper around the Write trait that counts how many bytes have been written in total.
/// Heavily inspired by https://stackoverflow.com/a/42189386
pub struct CountingWrite<W> {
inner: W,
count: usize,
}
impl<W> CountingWrite<W>
where
W: Write,
{
pub fn new(writer: W) -> Self {
Self {
inner: writer,
count: 0,
}
}
pub fn bytes_written(&self) -> usize {
self.count
}
}
impl<W> Write for CountingWrite<W>
where
W: Write,
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let res = self.inner.write(buf);
if let Ok(count) = res {
self.count += count;
}
res
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}

View file

@ -1,4 +1,5 @@
mod delta;
mod io_ext;
pub mod manager;
mod path;
@ -30,6 +31,7 @@ pub enum BackupType {
pub struct Backup<T: Clone> {
/// When the backup was started (also corresponds to the name)
pub start_time: chrono::DateTime<Utc>,
pub size: usize,
/// Type of the backup
pub type_: BackupType,
pub delta: Delta,
@ -84,7 +86,7 @@ impl<T: Clone> Backup<T> {
let start_time = chrono::offset::Utc::now();
let path = Backup::path(backup_dir, start_time);
let tar_gz = File::create(path)?;
let tar_gz = io_ext::CountingWrite::new(File::create(path)?);
let enc = GzEncoder::new(tar_gz, Compression::default());
let mut ar = tar::Builder::new(enc);
@ -104,9 +106,16 @@ impl<T: Clone> Backup<T> {
delta.added.insert(dir_in_tar.to_path_buf(), added_files);
}
let mut enc = ar.into_inner()?;
// The docs recommend running try_finish before unwrapping using finish
enc.try_finish()?;
let tar_gz = enc.finish()?;
Ok(Backup {
type_: BackupType::Full,
start_time,
size: tar_gz.bytes_written(),
delta,
metadata: None,
})
@ -122,7 +131,7 @@ impl<T: Clone> Backup<T> {
let start_time = chrono::offset::Utc::now();
let path = Backup::path(backup_dir, start_time);
let tar_gz = File::create(path)?;
let tar_gz = io_ext::CountingWrite::new(File::create(path)?);
let enc = GzEncoder::new(tar_gz, Compression::default());
let mut ar = tar::Builder::new(enc);
@ -154,9 +163,16 @@ impl<T: Clone> Backup<T> {
}
}
let mut enc = ar.into_inner()?;
// The docs recommend running try_finish before unwrapping using finish
enc.try_finish()?;
let tar_gz = enc.finish()?;
Ok(Backup {
type_: BackupType::Incremental,
start_time,
size: tar_gz.bytes_written(),
delta,
metadata: None,
})