#![cfg(feature = "cli")]
use std::{
fs,
io::{stdout, Write},
path::PathBuf,
};
use bitcut::{apply_patch, inspect, make_patch, Op};
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "bitcut")]
#[command(about = "Create and apply binary patches", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Diff { old: PathBuf, new: PathBuf },
Patch { old: PathBuf, patch: PathBuf },
Debug { patch: PathBuf },
}
fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Diff { old, new } => {
let old = fs::read(old)?;
let new = fs::read(new)?;
let patch = make_patch(&old, &new)?;
stdout().write_all(&patch)?;
}
Commands::Patch { old, patch } => {
let old = fs::read(old)?;
let patch = fs::read(patch)?;
let new = apply_patch(&old, &patch)?;
stdout().write_all(&new)?;
}
Commands::Debug { patch } => {
let patch = fs::read(patch)?;
match inspect(&patch)? {
Some(header) => println!("{header:#?}"),
None => println!("legacy patch: no header, base cannot be identified"),
}
let ops: Vec<_> = Op::iter(&patch).collect::<Result<_, _>>()?;
println!("{ops:#?}");
}
}
Ok(())
}