use std::io::Cursor;
use rusqlite::Error::UserFunctionError;
use crate::common_diff::{register_differ, Differ};
use crate::rusqlite::{Connection, Result};
pub fn register_bsdiffraw_functions(conn: &Connection) -> Result<()> {
register_differ::<BsdiffRawDiffer>(conn)
}
pub struct BsdiffRawDiffer;
impl Differ for BsdiffRawDiffer {
fn diff_name() -> &'static str {
"bsdiffraw"
}
fn patch_name() -> &'static str {
"bspatchraw"
}
fn diff(source: &[u8], target: &[u8]) -> Result<Vec<u8>> {
let mut patch = Vec::new();
bsdiff::diff(source, target, &mut patch).map_err(|e| UserFunctionError(e.into()))?;
Ok(patch)
}
fn patch(source: &[u8], patch: &[u8]) -> Result<Vec<u8>> {
let mut target = Vec::new();
bsdiff::patch(source, &mut Cursor::new(patch), &mut target)
.map_err(|e| UserFunctionError(e.into()))?;
Ok(target)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_diff() {
let source = b"abc013479zz";
let target = b"abc23456789zzf";
let patch = BsdiffRawDiffer::diff(source, target).unwrap();
let expected = b"\x03\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x32\x33\x34\x35\x36\x37\x38\x39\x7A\x7A\x66";
assert_eq!(patch, expected);
}
#[test]
fn test_patch() {
let source = b"abc013479zz";
let patch = b"\x03\x00\x00\x00\x00\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x32\x33\x34\x35\x36\x37\x38\x39\x7A\x7A\x66";
let target = BsdiffRawDiffer::patch(source, patch).unwrap();
let expected = b"abc23456789zzf";
assert_eq!(target, expected);
}
}