#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct Bounds {
pub(crate) lower: Vec<u8>,
pub(crate) upper: Option<Vec<u8>>,
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub(crate) struct Range {
pub(crate) prefix: Option<Vec<u8>>,
pub(crate) start: Option<Vec<u8>>,
pub(crate) end: Option<Vec<u8>>,
pub(crate) after: Option<Vec<u8>>,
}
impl Bounds {
pub(crate) fn new(range: &Range) -> Self {
let after = range.after.as_ref().map(|after| {
let mut next = after.clone();
next.push(0);
next
});
let lower = [range.prefix.clone(), range.start.clone(), after]
.into_iter()
.flatten()
.max()
.unwrap_or_default();
let upper = [
range.prefix.as_deref().and_then(prefix_end),
range.end.clone(),
]
.into_iter()
.flatten()
.min();
Self { lower, upper }
}
pub(crate) fn is_empty(&self) -> bool {
self.upper
.as_ref()
.is_some_and(|upper| *upper <= self.lower)
}
#[cfg(test)]
pub(crate) fn contains(&self, key: &[u8]) -> bool {
key >= self.lower.as_slice()
&& self
.upper
.as_ref()
.is_none_or(|upper| key < upper.as_slice())
}
}
pub(crate) fn prefix_end(prefix: &[u8]) -> Option<Vec<u8>> {
let last = prefix.iter().rposition(|&byte| byte != 0xFF)?;
let mut end = prefix[..=last].to_vec();
end[last] += 1;
Some(end)
}
#[cfg(test)]
mod tests;