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 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}