annotate rust/hg-core/src/bdiff.rs @ 52792:3ea5bd40b8dc

rust-nodemap: requiring immutable part to be Sync This is necessary for the upcoming PyO3 bindings and does not bring any problems. In practical applications, this immutable part is often obtained by `mmap` and satisfies the requirement.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Wed, 25 Dec 2024 12:43:45 +0100
parents 6183949219b2
children 3ac28aa1430e
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
52769
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
1 //! Safe bindings to bdiff.c.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
2
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
3 use crate::errors::HgError;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
4 use std::marker::PhantomData;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
5
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
6 /// A file split into lines, ready for diffing.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
7 pub struct Lines<'a> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
8 /// The array of lines, allocated by bdiff.c.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
9 /// Must never be mutated apart from freeing it in `Drop`.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
10 array: *mut ffi::bdiff_line,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
11 /// Length of the array.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
12 len: u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
13 /// Lifetime of the source buffer, since array items store pointers.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
14 _lifetime: PhantomData<&'a [u8]>,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
15 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
16
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
17 /// Splits `source` into lines that can be diffed.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
18 pub fn split_lines(source: &[u8]) -> Result<Lines, HgError> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
19 let mut array = std::ptr::null_mut();
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
20 // Safety: The pointer and length are valid since they both come from
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
21 // `source`, and the out pointer is non-null.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
22 let result = unsafe {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
23 ffi::bdiff_splitlines(
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
24 source.as_ptr() as *const std::ffi::c_char,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
25 source.len() as isize,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
26 &mut array,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
27 )
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
28 };
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
29 match u32::try_from(result) {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
30 Ok(len) => {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
31 assert!(!array.is_null());
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
32 Ok(Lines {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
33 array,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
34 len,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
35 _lifetime: PhantomData,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
36 })
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
37 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
38 Err(_) => {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
39 Err(HgError::abort_simple("bdiff_splitlines failed to allocate"))
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
40 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
41 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
42 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
43
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
44 impl<'a> Lines<'a> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
45 /// Returns the number of lines.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
46 pub fn len(&self) -> usize {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
47 self.len as usize
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
48 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
49
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
50 /// Returns an iterator over the lines.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
51 pub fn iter(&self) -> LinesIter<'_, 'a> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
52 LinesIter {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
53 lines: self,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
54 index: 0,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
55 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
56 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
57 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
58
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
59 impl Drop for Lines<'_> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
60 fn drop(&mut self) {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
61 // Safety: This is the only place that frees the array (no
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
62 // double-free), and it's in a `Drop` impl (no use-after-free).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
63 unsafe {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
64 libc::free(self.array as *mut std::ffi::c_void);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
65 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
66 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
67 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
68
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
69 // Safety: It is safe for multiple threads to share `&Lines` because
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
70 // `self.array` is never mutated except in `Drop`.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
71 unsafe impl Sync for Lines<'_> {}
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
72
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
73 // Safety: It is safe to send `Lines` to a different thread because
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
74 // `self.array` is never copied so only one thread will free it.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
75 unsafe impl Send for Lines<'_> {}
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
76
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
77 #[derive(Clone)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
78 pub struct LinesIter<'a, 'b> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
79 lines: &'a Lines<'b>,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
80 index: usize,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
81 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
82
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
83 impl<'b> Iterator for LinesIter<'_, 'b> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
84 type Item = &'b [u8];
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
85
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
86 fn next(&mut self) -> Option<Self::Item> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
87 if self.index == self.lines.len() {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
88 return None;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
89 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
90 // Safety: We just checked that the index has not reached the length.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
91 let line = unsafe { *self.lines.array.add(self.index) };
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
92 self.index += 1;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
93 // Safety: We assume bdiff.c sets `l` and `len` correctly.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
94 Some(unsafe {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
95 std::slice::from_raw_parts(line.l as *const u8, line.len as usize)
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
96 })
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
97 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
98
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
99 fn size_hint(&self) -> (usize, Option<usize>) {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
100 let len = self.lines.len() - self.index;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
101 (len, Some(len))
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
102 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
103 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
104
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
105 impl ExactSizeIterator for LinesIter<'_, '_> {}
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
106
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
107 /// A diff hunk comparing lines [a1,a2) in file A with lines [b1,b2) in file B.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
108 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
109 pub struct Hunk {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
110 /// Start line index in file A (inclusive).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
111 pub a1: u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
112 /// End line index in file A (exclusive).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
113 pub a2: u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
114 /// Start line index in file B (inclusive).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
115 pub b1: u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
116 /// End line index in file B (exclusive).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
117 pub b2: u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
118 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
119
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
120 /// A list of matching hunks.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
121 pub struct HunkList {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
122 /// The head of the linked list, allocated by bdiff.c.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
123 head: *mut ffi::bdiff_hunk,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
124 /// Length of the list.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
125 len: u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
126 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
127
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
128 /// Returns a list of hunks that match in `a` and `b`.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
129 pub fn diff(a: &Lines, b: &Lines) -> Result<HunkList, HgError> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
130 let mut out = ffi::bdiff_hunk {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
131 a1: 0,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
132 a2: 0,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
133 b1: 0,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
134 b2: 0,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
135 next: std::ptr::null_mut(),
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
136 };
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
137 // Safety: We assume bdiff.c sets `array` and `len` correctly; and the
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
138 // out pointer is non-null.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
139 let result = unsafe {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
140 ffi::bdiff_diff(a.array, a.len as i32, b.array, b.len as i32, &mut out)
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
141 };
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
142 match u32::try_from(result) {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
143 Ok(len) => Ok(HunkList {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
144 // Start with out.next because the first hunk is not meaningful and
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
145 // is not included in len. This matches mercurial/cffi/bdiff.py.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
146 head: out.next,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
147 len,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
148 }),
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
149 Err(_) => Err(HgError::abort_simple("bdiff_diff failed to allocate")),
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
150 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
151 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
152
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
153 impl HunkList {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
154 /// Returns the number of hunks.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
155 pub fn len(&self) -> usize {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
156 self.len as usize
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
157 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
158
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
159 /// Returns an iterator over the hunks.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
160 pub fn iter(&self) -> HunkListIter {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
161 HunkListIter {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
162 // Safety: If `self.head` is null, this is safe. If non-null, then:
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
163 // - We assume bdiff.c made it properly aligned.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
164 // - It's dereferenceable (any bit pattern is ok for `bdiff_hunk`).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
165 // - It won't be mutated because `HunkListIter` is tied to `&self`.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
166 next: unsafe { self.head.as_ref() },
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
167 remaining: self.len(),
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
168 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
169 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
170 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
171
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
172 impl Drop for HunkList {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
173 fn drop(&mut self) {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
174 // Safety: This is the only place that frees `self.head` (no
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
175 // double-free), and it's in a `Drop` impl (no use-after-free).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
176 unsafe {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
177 ffi::bdiff_freehunks(self.head);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
178 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
179 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
180 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
181
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
182 pub struct HunkListIter<'a> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
183 next: Option<&'a ffi::bdiff_hunk>,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
184 remaining: usize,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
185 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
186
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
187 impl Iterator for HunkListIter<'_> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
188 type Item = Hunk;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
189
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
190 fn next(&mut self) -> Option<Self::Item> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
191 match self.next {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
192 Some(hunk) => {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
193 // Safety: Same reasoning as in `HunkList::iter`.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
194 self.next = unsafe { hunk.next.as_ref() };
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
195 self.remaining -= 1;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
196 debug_assert_eq!(hunk.a2 - hunk.a1, hunk.b2 - hunk.b1);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
197 Some(Hunk {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
198 a1: hunk.a1 as u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
199 a2: hunk.a2 as u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
200 b1: hunk.b1 as u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
201 b2: hunk.b2 as u32,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
202 })
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
203 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
204 None => {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
205 assert_eq!(self.remaining, 0);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
206 None
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
207 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
208 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
209 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
210
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
211 fn size_hint(&self) -> (usize, Option<usize>) {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
212 (self.remaining, Some(self.remaining))
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
213 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
214 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
215
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
216 impl ExactSizeIterator for HunkListIter<'_> {}
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
217
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
218 mod ffi {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
219 #![allow(non_camel_case_types)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
220
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
221 use std::ffi::{c_char, c_int};
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
222
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
223 #[repr(C)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
224 #[derive(Debug, Copy, Clone)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
225 pub struct bdiff_line {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
226 pub hash: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
227 pub n: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
228 pub e: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
229 pub len: isize,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
230 pub l: *const c_char,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
231 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
232
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
233 #[repr(C)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
234 #[derive(Debug, Copy, Clone)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
235 pub struct bdiff_hunk {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
236 pub a1: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
237 pub a2: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
238 pub b1: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
239 pub b2: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
240 pub next: *mut bdiff_hunk,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
241 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
242
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
243 #[link(name = "bdiff", kind = "static")]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
244 extern "C" {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
245 /// Splits `a` into lines. On success, stores a pointer to an array of
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
246 /// lines in `*lr` and returns its length. On failure, returns
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
247 /// -1. The caller is responsible for freeing the array.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
248 ///
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
249 /// # Safety
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
250 ///
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
251 /// - `a` must point to an array of `len` chars.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
252 /// - `lr` must be non-null (but `*lr` can be null).
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
253 pub fn bdiff_splitlines(
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
254 a: *const c_char,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
255 len: isize,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
256 lr: *mut *mut bdiff_line,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
257 ) -> c_int;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
258
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
259 /// Diffs `a` and `b`. On success, stores the head of a linked list of
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
260 /// hunks in `base->next` and returns its length. On failure, returns
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
261 /// -1. The caller is responsible for `bdiff_freehunks(base->next)`.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
262 ///
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
263 /// # Safety
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
264 ///
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
265 /// - `a` must point to an array of `an` lines.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
266 /// - `b` must point to an array of `bn` lines.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
267 /// - `base` must be non-null.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
268 pub fn bdiff_diff(
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
269 a: *mut bdiff_line,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
270 an: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
271 b: *mut bdiff_line,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
272 bn: c_int,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
273 base: *mut bdiff_hunk,
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
274 ) -> c_int;
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
275
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
276 /// Frees the linked list of hunks `l`.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
277 ///
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
278 /// # Safety
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
279 ///
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
280 /// - `l` must be non-null, not already freed, and not used after this.
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
281 pub fn bdiff_freehunks(l: *mut bdiff_hunk);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
282 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
283 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
284
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
285 #[cfg(test)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
286 mod tests {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
287 fn split(a: &[u8]) -> Vec<&[u8]> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
288 super::split_lines(a).unwrap().iter().collect()
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
289 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
290
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
291 fn diff(a: &[u8], b: &[u8]) -> Vec<(u32, u32, u32, u32)> {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
292 let la = super::split_lines(a).unwrap();
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
293 let lb = super::split_lines(b).unwrap();
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
294 let hunks = super::diff(&la, &lb).unwrap();
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
295 hunks.iter().map(|h| (h.a1, h.a2, h.b1, h.b2)).collect()
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
296 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
297
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
298 #[test]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
299 fn test_split_lines() {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
300 assert_eq!(split(b""), [] as [&[u8]; 0]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
301 assert_eq!(split(b"\n"), [b"\n"]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
302 assert_eq!(split(b"\r\n"), [b"\r\n"]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
303 assert_eq!(split(b"X\nY"), [b"X\n" as &[u8], b"Y"]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
304 assert_eq!(split(b"X\nY\n"), [b"X\n" as &[u8], b"Y\n"]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
305 assert_eq!(split(b"X\r\nY\r\n"), [b"X\r\n" as &[u8], b"Y\r\n"]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
306 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
307
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
308 #[test]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
309 fn test_diff_single_line() {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
310 assert_eq!(diff(b"", b""), &[(0, 0, 0, 0)]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
311 assert_eq!(diff(b"x", b"x"), &[(0, 1, 0, 1), (1, 1, 1, 1)]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
312 assert_eq!(diff(b"x", b"y"), &[(1, 1, 1, 1)]);
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
313 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
314
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
315 #[test]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
316 fn test_diff_multiple_lines() {
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
317 assert_eq!(
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
318 diff(
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
319 b" line1 \n line2 \n line3 \n line4 \n REMOVED \n",
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
320 b" ADDED \n line1 \n lined2_CHANGED \n line3 \n line4 \n"
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
321 ),
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
322 &[(0, 1, 1, 2), (2, 4, 3, 5), (5, 5, 5, 5)]
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
323 );
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
324 }
1b7a57a5b47a rust: add safe bindings to bdiff.c
Mitchell Kember <mkember@janestreet.com>
parents:
diff changeset
325 }