extern crate gumdrop;
extern crate librsyncr as rsync;
use std::fs::File;
use std::io::{self, BufReader, BufWriter};
use gumdrop::Options;
#[derive(Debug, Options)]
struct CliOptions {
help: bool,
#[options(command)]
command: Option<Command>,
}
#[derive(Debug, Options)]
enum Command {
#[options(help = "Creates a signature file")]
Signature(SigOptions),
#[options(help = "Creates a delta file")]
Delta(DeltaOptions),
#[options(help = "Applies a delta file")]
Patch(PatchOptions),
}
#[derive(Debug, Options)]
struct SigOptions {
#[options(free)]
old_file: String,
#[options(free)]
signature_file: String,
#[options(help = "The bytes per block")]
block_size: u32,
#[options(short = "S",
help = "Set to smaller than the strong sum size (32 for Blake2) to truncate it")]
sum_size: u32,
}
#[derive(Debug, Options)]
struct DeltaOptions {
#[options(free)]
signature_file: String,
#[options(free)]
new_file: String,
#[options(free)]
delta_file: String,
}
#[derive(Debug, Options)]
struct PatchOptions {
#[options(free)]
old_file: String,
#[options(free)]
delta_file: String,
#[options(free)]
new_file: String,
}
fn main() -> Result<(), io::Error> {
let opts = CliOptions::parse_args_default_or_exit();
match opts.command {
Some(Command::Signature(sig_opts)) => {
let old_file_reader = BufReader::new(File::open(sig_opts.old_file)?);
let sig_file_writer = BufWriter::new(File::create(sig_opts.signature_file)?);
rsync::calculate_signature(old_file_reader, sig_file_writer)?;
},
Some(Command::Delta(delta_opts)) => {
let sig_file_reader = BufReader::new(File::open(delta_opts.signature_file)?);
let new_file_reader = BufReader::new(File::open(delta_opts.new_file)?);
let delta_file_writer = BufWriter::new(File::create(delta_opts.delta_file)?);
rsync::calculate_delta(sig_file_reader, new_file_reader, delta_file_writer).unwrap();
},
Some(Command::Patch(patch_opts)) => {
let old_file_reader = BufReader::new(File::open(patch_opts.old_file)?);
let delta_file_reader = BufReader::new(File::open(patch_opts.delta_file)?);
let new_file_writer = BufWriter::new(File::create(patch_opts.new_file)?);
rsync::apply_delta(old_file_reader, delta_file_reader, new_file_writer).unwrap();
},
_ => println!("{}", CliOptions::usage()),
}
Ok(())
}