Improve compact diff API (#24)

* Remove is_binary from API

* Format

* Rename file

* Test with more feature combinations

* Don't depend on serde for wasm

* Fix lint & tests

* Don't unwrap to MAX number

* Expose undiff to JS

* Add undiff tests

* Lint

* Change name
This commit is contained in:
Andras Schmelczer 2025-11-16 15:43:19 +00:00 committed by GitHub
parent 6191d1adb3
commit e85eb485e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 430 additions and 424 deletions

View file

@ -1,26 +0,0 @@
/// Heuristically determine if the given data is a binary or a text file's
/// content.
///
/// Only text inputs can be reconciled using the crate's functions.
#[must_use]
pub fn is_binary(data: &[u8]) -> bool {
if data.contains(&0) {
// Even though the NUL character is valid in UTF-8, it's highly suspicious in
// human-readable text.
return true;
}
std::str::from_utf8(data).is_err()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_binary() {
assert!(is_binary(&[0, 159, 146, 150]));
assert!(is_binary(&[0, 12]));
assert!(!is_binary(b"hello"));
}
}

View file

@ -87,7 +87,7 @@ struct V {
impl V {
fn new(max_d: usize) -> Self {
// max_d should fit in isize for the algorithm to work correctly
let offset = isize::try_from(max_d).unwrap_or(isize::MAX);
let offset = isize::try_from(max_d).expect("max_d must fit in isize");
Self {
offset,
v: vec![0; 2 * max_d],
@ -101,16 +101,15 @@ impl Index<isize> for V {
type Output = usize;
fn index(&self, index: isize) -> &Self::Output {
let idx = usize::try_from(index + self.offset).unwrap_or(usize::MAX);
&self.v[idx.min(self.v.len().saturating_sub(1))]
let idx = usize::try_from(index + self.offset).expect("index + offset must fit in usize");
&self.v[idx]
}
}
impl IndexMut<isize> for V {
fn index_mut(&mut self, index: isize) -> &mut Self::Output {
let idx = usize::try_from(index + self.offset).unwrap_or(usize::MAX);
let len = self.v.len();
&mut self.v[idx.min(len.saturating_sub(1))]
let idx = usize::try_from(index + self.offset).expect("index + offset must fit in usize");
&mut self.v[idx]
}
}
@ -145,7 +144,8 @@ where
// By Lemma 1 in the paper, the optimal edit script length is odd or even as
// `delta` is odd or even.
let delta = isize::try_from(n).unwrap_or(isize::MAX) - isize::try_from(m).unwrap_or(isize::MAX);
let delta = isize::try_from(n).expect("n must fit in isize")
- isize::try_from(m).expect("m must fit in isize");
let odd = delta & 1 == 1;
// The initial point at (0, -1)
@ -157,7 +157,7 @@ where
assert!(vf.len() >= d_max);
assert!(vb.len() >= d_max);
let d_max_isize = isize::try_from(d_max).unwrap_or(isize::MAX);
let d_max_isize = isize::try_from(d_max).expect("d_max must fit in isize");
for d in 0..d_max_isize {
// Forward path
for k in (-d..=d).rev().step_by(2) {
@ -166,7 +166,8 @@ where
} else {
vf[k - 1] + 1
};
let y = usize::try_from(isize::try_from(x).unwrap_or(isize::MAX) - k).unwrap_or(0);
let y = usize::try_from(isize::try_from(x).expect("x must fit in isize") - k)
.expect("x - k must be non-negative and fit in usize");
// The coordinate of the start of a snake
let (x0, y0) = (x, y);
@ -204,7 +205,8 @@ where
} else {
vb[k - 1] + 1
};
let mut y = usize::try_from(isize::try_from(x).unwrap_or(isize::MAX) - k).unwrap_or(0);
let mut y = usize::try_from(isize::try_from(x).expect("x must fit in isize") - k)
.expect("x - k must be non-negative and fit in usize");
// The coordinate of the start of a snake
if x < n && y < m {