Skip to main content

stackforge_core/utils/
compare.rs

1//! Binary comparison and diff utilities.
2
3use std::fmt::Write;
4
5/// Compare two byte slices and return the first differing index.
6pub fn find_diff(a: &[u8], b: &[u8]) -> Option<usize> {
7    let min_len = a.len().min(b.len());
8
9    for i in 0..min_len {
10        if a[i] != b[i] {
11            return Some(i);
12        }
13    }
14
15    if a.len() != b.len() {
16        Some(min_len)
17    } else {
18        None
19    }
20}
21
22/// Generate a diff between two byte slices.
23pub fn byte_diff(a: &[u8], b: &[u8]) -> String {
24    let mut output = String::new();
25    let max_len = a.len().max(b.len());
26
27    writeln!(output, "Comparing {} bytes vs {} bytes", a.len(), b.len()).unwrap();
28
29    for i in 0..max_len {
30        let byte_a = a.get(i).copied();
31        let byte_b = b.get(i).copied();
32
33        if byte_a != byte_b {
34            let a_str = byte_a
35                .map(|b| format!("{:02x}", b))
36                .unwrap_or_else(|| "--".to_string());
37            let b_str = byte_b
38                .map(|b| format!("{:02x}", b))
39                .unwrap_or_else(|| "--".to_string());
40            writeln!(output, "  offset {:04x}: {} != {}", i, a_str, b_str).unwrap();
41        }
42    }
43
44    output
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_find_diff() {
53        let a = [1, 2, 3, 4, 5];
54        let b = [1, 2, 9, 4, 5];
55        assert_eq!(find_diff(&a, &b), Some(2));
56
57        let c = [1, 2, 3, 4, 5];
58        assert_eq!(find_diff(&a, &c), None);
59
60        let d = [1, 2, 3];
61        assert_eq!(find_diff(&a, &d), Some(3));
62    }
63}