1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#[cfg(test)]
use sha2::{Digest, Sha256};

#[cfg(test)]
pub(crate) fn length_field(value: impl AsRef<[u8]>) -> [u8; 8] {
    let length: u64 = value.as_ref().len().try_into().unwrap();
    length.to_le_bytes()
}

#[cfg(test)]
pub(crate) fn sha256(data: impl AsRef<[u8]>) -> [u8; 32] {
    let mut state = Sha256::default();
    state.update(data.as_ref());
    state.finalize().into()
}

/// Find the offset of a `needle` within a large `haystack` allocation.
///
/// # Panics
///
/// This will panic if the needle lies outside of the allocation.
#[track_caller]
pub(crate) fn subslice_offsets(haystack: &[u8], needle: &[u8]) -> std::ops::Range<usize> {
    let haystack_range = haystack.as_ptr_range();
    let needle_range = needle.as_ptr_range();

    assert!(
        haystack_range.start <= needle_range.start && needle_range.end <= haystack_range.end,
        "expected {needle_range:?} to lie within {haystack_range:?}",
    );

    let start = (needle_range.start as usize)
        .checked_sub(haystack_range.start as usize)
        .expect("Needle out of range");
    let end = (needle_range.end as usize)
        .checked_sub(haystack_range.start as usize)
        .expect("Needle out of range");

    start..end
}