use std::ops::Bound;
use obj_core::IndexKind;
pub(crate) const SUFFIX_HIGH: [u8; 8] = [0xFF; 8];
pub(crate) fn widen_bounds_for_kind(
start: Bound<Vec<u8>>,
end: Bound<Vec<u8>>,
kind: IndexKind,
) -> (Bound<Vec<u8>>, Bound<Vec<u8>>) {
if kind == IndexKind::Unique {
return (start, end);
}
(widen_lower(start), widen_upper(end))
}
fn widen_lower(b: Bound<Vec<u8>>) -> Bound<Vec<u8>> {
match b {
Bound::Included(v) => Bound::Included(v),
Bound::Excluded(v) => Bound::Excluded(append_suffix_high(v)),
Bound::Unbounded => Bound::Unbounded,
}
}
fn widen_upper(b: Bound<Vec<u8>>) -> Bound<Vec<u8>> {
match b {
Bound::Included(v) => Bound::Included(append_suffix_high(v)),
Bound::Excluded(v) => Bound::Excluded(v),
Bound::Unbounded => Bound::Unbounded,
}
}
fn append_suffix_high(mut v: Vec<u8>) -> Vec<u8> {
v.extend_from_slice(&SUFFIX_HIGH);
v
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unique_pass_through() {
let (s, e) = widen_bounds_for_kind(
Bound::Included(b"abc".to_vec()),
Bound::Included(b"abc".to_vec()),
IndexKind::Unique,
);
assert_eq!(s, Bound::Included(b"abc".to_vec()));
assert_eq!(e, Bound::Included(b"abc".to_vec()));
}
#[test]
fn standard_included_upper_widens() {
let (_s, e) = widen_bounds_for_kind(
Bound::Included(b"a".to_vec()),
Bound::Included(b"a".to_vec()),
IndexKind::Standard,
);
let mut expected = b"a".to_vec();
expected.extend_from_slice(&[0xFF; 8]);
assert_eq!(e, Bound::Included(expected));
}
#[test]
fn standard_excluded_lower_widens() {
let (s, _e) = widen_bounds_for_kind(
Bound::Excluded(b"a".to_vec()),
Bound::Unbounded,
IndexKind::Standard,
);
let mut expected = b"a".to_vec();
expected.extend_from_slice(&[0xFF; 8]);
assert_eq!(s, Bound::Excluded(expected));
}
#[test]
fn excluded_upper_and_included_lower_unchanged_for_non_unique() {
let (s, e) = widen_bounds_for_kind(
Bound::Included(b"lo".to_vec()),
Bound::Excluded(b"hi".to_vec()),
IndexKind::Each,
);
assert_eq!(s, Bound::Included(b"lo".to_vec()));
assert_eq!(e, Bound::Excluded(b"hi".to_vec()));
}
#[test]
fn unbounded_pass_through_for_all_kinds() {
for kind in [
IndexKind::Standard,
IndexKind::Unique,
IndexKind::Each,
IndexKind::Composite,
] {
let (s, e) = widen_bounds_for_kind(Bound::Unbounded, Bound::Unbounded, kind);
assert_eq!(s, Bound::Unbounded);
assert_eq!(e, Bound::Unbounded);
}
}
}