Skip to main content

apply_bytes

Function apply_bytes 

Source
pub fn apply_bytes(
    base_image: &[u8],
    patch: &Patch<'_, [u8]>,
) -> Result<Vec<u8>, ApplyError>
Expand description

Apply a non-utf8 Patch to a base image

ยงExamples

use diffy::Patch;
use diffy::apply_bytes;

let patch = Patch::from_bytes(
    b"\
--- a/ideals
+++ b/ideals
@@ -1 +1,2 @@
 First Ideal
+Second Ideal
",
)
.unwrap();

let applied = apply_bytes(b"First Ideal\n", &patch).unwrap();

assert_eq!(
    applied,
    b"\
First Ideal
Second Ideal
",
);
Examples found in repository?
examples/apply.rs (line 63)
42fn apply_patch_file(patch_file: &Path, dst: &Path) -> Result<(), Box<dyn std::error::Error>> {
43    let content = fs::read(patch_file)?;
44
45    let patches = PatchSet::parse_bytes(&content, ParseOptions::gitdiff());
46
47    for file_patch in patches {
48        let file_patch = file_patch?;
49        let operation = {
50            let op = file_patch.operation();
51            // Rename/Copy paths come from git headers without a/b prefix.
52            let strip = match op {
53                FileOperation::Rename { .. } | FileOperation::Copy { .. } => 0,
54                _ => 1,
55            };
56            op.strip_prefix(strip)
57        };
58
59        match operation {
60            FileOperation::Create(path) => {
61                let target = dst.join(path_from_bytes(&path)?);
62                let patched = match file_patch.patch() {
63                    PatchKind::Text(patch) => apply_bytes(&[], patch)?,
64                    PatchKind::Binary(BinaryPatch::Marker) => continue,
65                    PatchKind::Binary(patch) => patch.apply(&[])?,
66                };
67                create_parent_dirs(&target)?;
68                fs::write(&target, patched)?;
69                eprintln!("create {}", target.display());
70            }
71            FileOperation::Delete(path) => {
72                let target = dst.join(path_from_bytes(&path)?);
73                fs::remove_file(&target)?;
74                eprintln!("delete {}", target.display());
75            }
76            FileOperation::Modify { original, modified } => {
77                let src_path = dst.join(path_from_bytes(&original)?);
78                let dst_path = dst.join(path_from_bytes(&modified)?);
79                let patched = match file_patch.patch() {
80                    PatchKind::Text(patch) => {
81                        let base = fs::read(&src_path)?;
82                        apply_bytes(&base, patch)?
83                    }
84                    PatchKind::Binary(BinaryPatch::Marker) => continue,
85                    PatchKind::Binary(patch) => {
86                        let base = fs::read(&src_path)?;
87                        patch.apply(&base)?
88                    }
89                };
90                create_parent_dirs(&dst_path)?;
91                fs::write(&dst_path, patched)?;
92                if src_path != dst_path {
93                    fs::remove_file(&src_path)?;
94                    eprintln!("rename {} -> {}", src_path.display(), dst_path.display());
95                } else {
96                    eprintln!("modify {}", dst_path.display());
97                }
98            }
99            FileOperation::Rename { from, to } => {
100                let src_path = dst.join(path_from_bytes(&from)?);
101                let dst_path = dst.join(path_from_bytes(&to)?);
102                create_parent_dirs(&dst_path)?;
103                fs::rename(&src_path, &dst_path)?;
104                eprintln!("rename {} -> {}", src_path.display(), dst_path.display());
105            }
106            FileOperation::Copy { from, to } => {
107                let src_path = dst.join(path_from_bytes(&from)?);
108                let dst_path = dst.join(path_from_bytes(&to)?);
109                create_parent_dirs(&dst_path)?;
110                fs::copy(&src_path, &dst_path)?;
111                eprintln!("copy {} -> {}", src_path.display(), dst_path.display());
112            }
113        }
114    }
115
116    Ok(())
117}