pub struct ParseOptions { /* private fields */ }Expand description
Options for parsing patch content.
Use ParseOptions::unidiff() or ParseOptions::gitdiff()
to create options for the desired format.
§Binary Files
When parsing git diffs, binary file changes are detected by:
Binary files a/path and b/path differ(git diffwithout--binaryflag)GIT binary patch(fromgit diff --binary)
Note that this is not a documented Git behavior, so the implementation here is subject to change if Git changes.
§Example
use diffy::patch_set::ParseOptions;
use diffy::patch_set::PatchSet;
let s = "\
--- original
+++ modified
@@ -1 +1 @@
-old
+new
";
let patches: Vec<_> = PatchSet::parse(s, ParseOptions::unidiff())
.collect::<Result<_, _>>()
.unwrap();
assert_eq!(patches.len(), 1);Implementations§
Source§impl ParseOptions
impl ParseOptions
Sourcepub fn unidiff() -> Self
pub fn unidiff() -> Self
Parse as standard unified diff format.
Supported:
---/+++file headers@@ ... @@hunks- modify and rename files
- create files (
--- /dev/null) - delete files (
+++ /dev/null) - Skip preamble, headers, and email signature trailer
Sourcepub fn gitdiff() -> Self
pub fn gitdiff() -> Self
Parse as git extended diff format.
Supports all features of unidiff() plus:
diff --githeaders- Extended headers (
new file mode,deleted file mode, etc.) - Rename/copy detection (
rename from/rename to,copy from/copy to) - Binary file detection
Examples found in repository?
examples/apply.rs (line 45)
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}Trait Implementations§
Source§impl Clone for ParseOptions
impl Clone for ParseOptions
Source§fn clone(&self) -> ParseOptions
fn clone(&self) -> ParseOptions
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait Implementations§
impl Freeze for ParseOptions
impl RefUnwindSafe for ParseOptions
impl Send for ParseOptions
impl Sync for ParseOptions
impl Unpin for ParseOptions
impl UnsafeUnpin for ParseOptions
impl UnwindSafe for ParseOptions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more