renaming
This commit is contained in:
70
src/zspatch.rs
Normal file
70
src/zspatch.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
mod utils;
|
||||
|
||||
use clap::Parser;
|
||||
use std::fs::read;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
use std::{fs, io};
|
||||
use utils::Zsdiff;
|
||||
|
||||
async fn create_tmp_dir(dir_name: String) -> Result<String, io::Error> {
|
||||
let name = format!("{}.tmp", dir_name);
|
||||
fs::remove_dir_all(name.clone()).ok();
|
||||
fs::DirBuilder::new().create(name.clone())?;
|
||||
Ok(name)
|
||||
}
|
||||
|
||||
async fn extract_files(zsdiff: &Zsdiff, filename: &String) -> Result<String, io::Error> {
|
||||
let tmp_dir_name = create_tmp_dir(filename.to_string()).await?;
|
||||
let path = Path::new(&tmp_dir_name);
|
||||
fs::remove_dir_all(path).ok();
|
||||
for (f, c) in zsdiff.content.iter() {
|
||||
let filepath = path.join(f);
|
||||
fs::create_dir_all(filepath.parent().unwrap())?;
|
||||
fs::File::create(&filepath)?.write_all(c)?;
|
||||
}
|
||||
Ok(tmp_dir_name)
|
||||
}
|
||||
|
||||
async fn zpatch(filename: String, dest_dir: String) -> Result<(), io::Error> {
|
||||
let filename = &format!("{}.zdiff", filename);
|
||||
let parts = utils::decompress_parts(read(filename)?).await?;
|
||||
let diff = Zsdiff::from_vec(parts).await?;
|
||||
let tmp_dir_name = extract_files(&diff, filename).await?;
|
||||
for name in diff.content.keys().collect::<Vec<&String>>() {
|
||||
let from_path = Path::new(&tmp_dir_name).join(name);
|
||||
let to_path = Path::new(&dest_dir).join(name);
|
||||
fs::create_dir_all(to_path.parent().unwrap())?;
|
||||
fs::copy(from_path, to_path)?;
|
||||
}
|
||||
|
||||
for file in diff.metadata.remove_files {
|
||||
let path = Path::new(&dest_dir).join(file);
|
||||
fs::remove_file(path).ok();
|
||||
}
|
||||
|
||||
for (k, hash) in diff.metadata.hashes {
|
||||
let path = Path::new(&dest_dir).join(k);
|
||||
let content = read(path)?;
|
||||
let fs_hash = utils::get_hash(&content).await;
|
||||
if !fs_hash.eq(&hash) {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "Hash mismatch"))?
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Args {
|
||||
#[arg(short, long)]
|
||||
filename: String,
|
||||
#[arg(short, long)]
|
||||
dest_dir: String,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> io::Result<()> {
|
||||
let args = Args::parse();
|
||||
zpatch(args.filename, args.dest_dir).await?;
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user