Skip to content

Commit ecd56b0

Browse files
authored
Tie Patch lifetime to its input buffers (#523)
1 parent 9071a87 commit ecd56b0

File tree

1 file changed

+26
-21
lines changed

1 file changed

+26
-21
lines changed

src/patch.rs

+26-21
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use libc::{c_int, c_void};
2+
use std::marker::PhantomData;
23
use std::path::Path;
34
use std::ptr;
45

@@ -9,33 +10,37 @@ use crate::{raw, Blob, Buf, Diff, DiffDelta, DiffHunk, DiffLine, DiffOptions, Er
910
/// A structure representing the text changes in a single diff delta.
1011
///
1112
/// This is an opaque structure.
12-
pub struct Patch {
13+
pub struct Patch<'buffers> {
1314
raw: *mut raw::git_patch,
15+
buffers: PhantomData<&'buffers ()>,
1416
}
1517

16-
unsafe impl Send for Patch {}
18+
unsafe impl<'buffers> Send for Patch<'buffers> {}
1719

18-
impl Binding for Patch {
20+
impl<'buffers> Binding for Patch<'buffers> {
1921
type Raw = *mut raw::git_patch;
20-
unsafe fn from_raw(raw: Self::Raw) -> Patch {
21-
Patch { raw: raw }
22+
unsafe fn from_raw(raw: Self::Raw) -> Self {
23+
Patch {
24+
raw: raw,
25+
buffers: PhantomData,
26+
}
2227
}
2328
fn raw(&self) -> Self::Raw {
2429
self.raw
2530
}
2631
}
2732

28-
impl Drop for Patch {
33+
impl<'buffers> Drop for Patch<'buffers> {
2934
fn drop(&mut self) {
3035
unsafe { raw::git_patch_free(self.raw) }
3136
}
3237
}
3338

34-
impl Patch {
39+
impl<'buffers> Patch<'buffers> {
3540
/// Return a Patch for one file in a Diff.
3641
///
3742
/// Returns Ok(None) for an unchanged or binary file.
38-
pub fn from_diff(diff: &Diff<'_>, idx: usize) -> Result<Option<Patch>, Error> {
43+
pub fn from_diff(diff: &Diff<'buffers>, idx: usize) -> Result<Option<Self>, Error> {
3944
let mut ret = ptr::null_mut();
4045
unsafe {
4146
try_call!(raw::git_patch_from_diff(&mut ret, diff.raw(), idx));
@@ -45,12 +50,12 @@ impl Patch {
4550

4651
/// Generate a Patch by diffing two blobs.
4752
pub fn from_blobs(
48-
old_blob: &Blob<'_>,
53+
old_blob: &Blob<'buffers>,
4954
old_path: Option<&Path>,
50-
new_blob: &Blob<'_>,
55+
new_blob: &Blob<'buffers>,
5156
new_path: Option<&Path>,
5257
opts: Option<&mut DiffOptions>,
53-
) -> Result<Patch, Error> {
58+
) -> Result<Self, Error> {
5459
let mut ret = ptr::null_mut();
5560
let old_path = into_opt_c_string(old_path)?;
5661
let new_path = into_opt_c_string(new_path)?;
@@ -69,12 +74,12 @@ impl Patch {
6974

7075
/// Generate a Patch by diffing a blob and a buffer.
7176
pub fn from_blob_and_buffer(
72-
old_blob: &Blob<'_>,
77+
old_blob: &Blob<'buffers>,
7378
old_path: Option<&Path>,
74-
new_buffer: &[u8],
79+
new_buffer: &'buffers [u8],
7580
new_path: Option<&Path>,
7681
opts: Option<&mut DiffOptions>,
77-
) -> Result<Patch, Error> {
82+
) -> Result<Self, Error> {
7883
let mut ret = ptr::null_mut();
7984
let old_path = into_opt_c_string(old_path)?;
8085
let new_path = into_opt_c_string(new_path)?;
@@ -94,12 +99,12 @@ impl Patch {
9499

95100
/// Generate a Patch by diffing two buffers.
96101
pub fn from_buffers(
97-
old_buffer: &[u8],
102+
old_buffer: &'buffers [u8],
98103
old_path: Option<&Path>,
99-
new_buffer: &[u8],
104+
new_buffer: &'buffers [u8],
100105
new_path: Option<&Path>,
101106
opts: Option<&mut DiffOptions>,
102-
) -> Result<Patch, Error> {
107+
) -> Result<Self, Error> {
103108
crate::init();
104109
let mut ret = ptr::null_mut();
105110
let old_path = into_opt_c_string(old_path)?;
@@ -120,7 +125,7 @@ impl Patch {
120125
}
121126

122127
/// Get the DiffDelta associated with the Patch.
123-
pub fn delta(&self) -> DiffDelta<'_> {
128+
pub fn delta(&self) -> DiffDelta<'buffers> {
124129
unsafe { Binding::from_raw(raw::git_patch_get_delta(self.raw) as *mut _) }
125130
}
126131

@@ -146,7 +151,7 @@ impl Patch {
146151
}
147152

148153
/// Get a DiffHunk and its total line count from the Patch.
149-
pub fn hunk(&self, hunk_idx: usize) -> Result<(DiffHunk<'_>, usize), Error> {
154+
pub fn hunk(&self, hunk_idx: usize) -> Result<(DiffHunk<'buffers>, usize), Error> {
150155
let mut ret = ptr::null();
151156
let mut lines = 0;
152157
unsafe {
@@ -167,7 +172,7 @@ impl Patch {
167172
&self,
168173
hunk_idx: usize,
169174
line_of_hunk: usize,
170-
) -> Result<DiffLine<'_>, Error> {
175+
) -> Result<DiffLine<'buffers>, Error> {
171176
let mut ret = ptr::null();
172177
unsafe {
173178
try_call!(raw::git_patch_get_line_in_hunk(
@@ -216,7 +221,7 @@ impl Patch {
216221
}
217222
}
218223

219-
impl std::fmt::Debug for Patch {
224+
impl<'buffers> std::fmt::Debug for Patch<'buffers> {
220225
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
221226
let mut ds = f.debug_struct("Patch");
222227
ds.field("delta", &self.delta())

0 commit comments

Comments
 (0)