use std::collections::BTreeSet;
pub type Trigram = [u8; 3];
#[inline]
pub fn pack(t: Trigram) -> u32 {
((t[0] as u32) << 16) | ((t[1] as u32) << 8) | (t[2] as u32)
}
#[inline]
pub fn for_each(bytes: &[u8], mut f: impl FnMut(Trigram)) {
for w in bytes.windows(3) {
f([w[0], w[1], w[2]]);
}
}
pub fn distinct(bytes: &[u8]) -> BTreeSet<Trigram> {
let mut set = BTreeSet::new();
for_each(bytes, |t| {
set.insert(t);
});
set
}
pub fn of_literal(lit: &[u8]) -> Vec<Trigram> {
lit.windows(3).map(|w| [w[0], w[1], w[2]]).collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn distinct_and_literal_agree() {
assert_eq!(of_literal(b"abcd"), vec![*b"abc", *b"bcd"]);
assert!(of_literal(b"ab").is_empty());
let d = distinct(b"abcabc");
assert_eq!(d.len(), 3);
assert!(d.contains(b"abc"));
}
}