#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeysetOp {
Gt,
Lt,
Eq,
}
impl KeysetOp {
#[must_use]
pub fn as_str(self) -> &'static str {
match self {
KeysetOp::Gt => "gt",
KeysetOp::Lt => "lt",
KeysetOp::Eq => "eq",
}
}
}
pub type Term = Vec<(usize, KeysetOp)>;
#[must_use]
pub fn keyset_terms(ascending: &[bool]) -> Vec<Term> {
(0..ascending.len())
.map(|i| {
let mut term: Term = (0..i).map(|j| (j, KeysetOp::Eq)).collect();
let op = if ascending[i] {
KeysetOp::Gt
} else {
KeysetOp::Lt
};
term.push((i, op));
term
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn single_ascending_key() {
assert_eq!(keyset_terms(&[true]), vec![vec![(0, KeysetOp::Gt)]]);
}
#[test]
fn single_descending_key() {
assert_eq!(keyset_terms(&[false]), vec![vec![(0, KeysetOp::Lt)]]);
}
#[test]
fn two_keys_asc_desc() {
assert_eq!(
keyset_terms(&[true, false]),
vec![
vec![(0, KeysetOp::Gt)],
vec![(0, KeysetOp::Eq), (1, KeysetOp::Lt)],
]
);
}
#[test]
fn three_keys_build_equality_prefix() {
let terms = keyset_terms(&[true, true, true]);
assert_eq!(terms.len(), 3);
assert_eq!(
terms[2],
vec![(0, KeysetOp::Eq), (1, KeysetOp::Eq), (2, KeysetOp::Gt)]
);
}
#[test]
fn empty_keys_yield_no_terms() {
assert!(keyset_terms(&[]).is_empty());
}
}