1use std::ops::{Bound, RangeBounds};
6
7use bincode::Options;
8use serde::Serialize;
9
10#[inline]
11pub fn be_fix_int_ser<S>(t: &S) -> Vec<u8>
12where
13 S: ?Sized + serde::Serialize,
14{
15 bincode::DefaultOptions::new()
16 .with_big_endian()
17 .with_fixint_encoding()
18 .serialize(t)
19 .expect("failed to serialize via be_fix_int_ser method")
20}
21
22pub(crate) fn iterator_bounds<K>(
23 lower_bound: Option<K>,
24 upper_bound: Option<K>,
25) -> (Option<Vec<u8>>, Option<Vec<u8>>)
26where
27 K: Serialize,
28{
29 (
30 lower_bound.map(|b| be_fix_int_ser(&b)),
31 upper_bound.map(|b| be_fix_int_ser(&b)),
32 )
33}
34
35pub(crate) fn iterator_bounds_with_range<K>(
36 range: impl RangeBounds<K>,
37) -> (Option<Vec<u8>>, Option<Vec<u8>>)
38where
39 K: Serialize,
40{
41 let iterator_lower_bound = match range.start_bound() {
42 Bound::Included(lower_bound) => {
43 Some(be_fix_int_ser(&lower_bound))
45 }
46 Bound::Excluded(lower_bound) => {
47 let mut key_buf = be_fix_int_ser(&lower_bound);
48
49 if is_max(&key_buf) {
50 key_buf.push(0);
55 } else {
56 big_endian_saturating_add_one(&mut key_buf);
58 }
59 Some(key_buf)
60 }
61 Bound::Unbounded => None,
62 };
63 let iterator_upper_bound = match range.end_bound() {
64 Bound::Included(upper_bound) => {
65 let mut key_buf = be_fix_int_ser(&upper_bound);
66
67 if !is_max(&key_buf) {
70 big_endian_saturating_add_one(&mut key_buf);
72 Some(key_buf)
73 } else {
74 None
75 }
76 }
77 Bound::Excluded(upper_bound) => {
78 Some(be_fix_int_ser(&upper_bound))
80 }
81 Bound::Unbounded => None,
82 };
83 (iterator_lower_bound, iterator_upper_bound)
84}
85
86fn big_endian_saturating_add_one(v: &mut [u8]) {
90 if is_max(v) {
91 return;
92 }
93 for i in (0..v.len()).rev() {
94 if v[i] == u8::MAX {
95 v[i] = 0;
96 } else {
97 v[i] += 1;
98 break;
99 }
100 }
101}
102
103fn is_max(v: &[u8]) -> bool {
105 v.iter().all(|&x| x == u8::MAX)
106}
107
108#[expect(clippy::assign_op_pattern, clippy::manual_div_ceil)]
109#[test]
110fn test_helpers() {
111 let v = vec![];
112 assert!(is_max(&v));
113
114 fn check_add(v: Vec<u8>) {
115 let mut v = v;
116 let num = Num32::from_big_endian(&v);
117 big_endian_saturating_add_one(&mut v);
118 assert!(num + 1 == Num32::from_big_endian(&v));
119 }
120
121 uint::construct_uint! {
122 struct Num32(4);
124 }
125
126 let mut v = vec![255; 32];
127 big_endian_saturating_add_one(&mut v);
128 assert!(Num32::MAX == Num32::from_big_endian(&v));
129
130 check_add(vec![1; 32]);
131 check_add(vec![6; 32]);
132 check_add(vec![254; 32]);
133
134 }