bigtable_rs/
util.rs

1use crate::google::bigtable::v2::row_range::{EndKey, StartKey};
2use crate::google::bigtable::v2::RowRange;
3
4pub fn get_row_range_from_prefix(prefix: Vec<u8>) -> RowRange {
5    let end_key = get_end_key_for_prefix(prefix.as_ref()).map(EndKey::EndKeyOpen);
6    RowRange {
7        start_key: Some(StartKey::StartKeyClosed(prefix)),
8        end_key,
9    }
10}
11
12fn get_end_key_for_prefix(start_key: &[u8]) -> Option<Vec<u8>> {
13    let size = start_key.len();
14    if size < 1 {
15        return None;
16    }
17
18    let mut vector = vec![0; size];
19    let mut carry = 1u8;
20
21    for (i, key_part) in start_key.iter().enumerate().rev() {
22        if *key_part != 0xFFu8 || carry == 0 {
23            vector[i] = *key_part + carry;
24            carry = 0;
25        }
26    }
27
28    if carry == 1 {
29        // overflow
30        return None;
31    }
32
33    Some(vector)
34}
35
36#[cfg(test)]
37mod tests {
38    use super::get_end_key_for_prefix;
39    #[test]
40    fn get_end_key_works() {
41        assert_eq!(get_end_key_for_prefix(&[]), None);
42        assert_eq!(get_end_key_for_prefix(&[0x01u8]), Some([0x02u8].to_vec()));
43        assert_eq!(
44            get_end_key_for_prefix(&[0x01u8, 0xFFu8]),
45            Some([0x02u8, 0x00u8].to_vec())
46        );
47        assert_eq!(
48            get_end_key_for_prefix(&[0x21u8, 0xFFu8]),
49            Some([0x22u8, 0x00u8].to_vec())
50        );
51        assert_eq!(
52            get_end_key_for_prefix(&[0xFFu8, 0xF1u8, 0xFFu8]),
53            Some([0xFFu8, 0xF2u8, 0x00u8].to_vec())
54        );
55        assert_eq!(get_end_key_for_prefix(&[0xFFu8]), None);
56    }
57}