Zillowe FoundationZillowe Documentation

Custom Patch Formats

Extend zbsdiff with custom storage and compression formats.

One of the unique features of zbsdiff is the ability to decouple the diffing engine from the patch storage format. This is achieved through the PatchWriter and PatchReader traits.

PatchWriter

Implement the PatchWriter trait to define how patch instructions and data are stored.

use zbsdiff::{Control, PatchWriter};

pub struct MyCustomWriter {
    // ... your storage (e.g. a database handle, custom compressor) ...
}

impl PatchWriter for MyCustomWriter {
    fn write_control(&mut self, ctrl: Control) -> std::io::Result<()> {
        // ... store control instruction ...
        Ok(())
    }

    fn write_delta(&mut self, delta: &[u8]) -> std::io::Result<()> {
        // ... store differential data ...
        Ok(())
    }

    fn write_extra(&mut self, extra: &[u8]) -> std::io::Result<()> {
        // ... store extra data ...
        Ok(())
    }

    fn finish(self) -> std::io::Result<u64> {
        // ... finalization ...
        Ok(0)
    }
}

Use it with Bsdiff::compare_with:

let writer = MyCustomWriter::new();
bsdiff.compare_with(writer)?;

PatchReader

Similarly, implement PatchReader to define how to retrieve patch data.

use zbsdiff::{Control, PatchReader};

impl PatchReader for MyCustomReader {
    fn target_size(&self) -> u64 { /* ... */ }
    fn read_control(&mut self) -> std::io::Result<Option<Control>> { /* ... */ }
    fn read_delta(&mut self, buf: &mut [u8]) -> std::io::Result<()> { /* ... */ }
    fn read_extra(&mut self, buf: &mut [u8]) -> std::io::Result<()> { /* ... */ }
}

Use it with Bspatch::apply_with:

let reader = MyCustomReader::new();
patcher.apply_with(reader, source, target)?;

A software organization

2026 © All Rights Reserved.

  • All the content is available under CC BY-SA 4.0, expect where otherwise stated.

Last updated on