use bytes::{BufMut, Bytes, BytesMut};
#[derive(Clone)]
pub(crate) struct OrderedBytesGenerator {
suffix: Bytes,
bytes: Vec<u8>,
min: u8,
max: u8,
}
impl OrderedBytesGenerator {
#[cfg(any(feature = "bencher", test))]
pub(crate) fn new_with_suffix(suffix: &[u8], bytes: &[u8]) -> Self {
Self::new(suffix, bytes, u8::MIN, u8::MAX)
}
#[cfg(test)]
pub(crate) fn new_with_byte_range(bytes: &[u8], min: u8, max: u8) -> Self {
Self::new(&[], bytes, min, max)
}
pub(crate) fn new(suffix: &[u8], bytes: &[u8], min: u8, max: u8) -> Self {
let bytes = Vec::from(bytes);
Self {
suffix: Bytes::copy_from_slice(suffix),
bytes,
min,
max,
}
}
pub(crate) fn next(&mut self) -> Bytes {
let mut result = BytesMut::with_capacity(self.bytes.len() + std::mem::size_of::<u32>());
result.put_slice(self.bytes.as_slice());
result.put(self.suffix.as_ref());
self.increment();
result.freeze()
}
fn increment(&mut self) {
let mut pos = self.bytes.len() - 1;
while self.bytes[pos] == self.max {
self.bytes[pos] = self.min;
pos -= 1;
}
self.bytes[pos] += 1;
}
}
#[cfg(test)]
mod tests {
use bytes::{BufMut, Bytes};
use crate::bytes_generator::OrderedBytesGenerator;
#[test]
fn test_should_generate_ordered_bytes() {
let mut suffix = Vec::<u8>::new();
suffix.put_u32(3735928559);
let start = [0u8, 0u8, 0u8];
let mut gen = OrderedBytesGenerator::new(suffix.as_ref(), &start, 0, 2);
let expected = [
[0u8, 0u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 0u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 0u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 1u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 1u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 1u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 2u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 2u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[0u8, 2u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 0u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 0u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 0u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 1u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 1u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 1u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 2u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 2u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[1u8, 2u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 0u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 0u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 0u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 1u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 1u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 1u8, 2u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 2u8, 0u8, 0xde, 0xad, 0xbe, 0xef],
[2u8, 2u8, 1u8, 0xde, 0xad, 0xbe, 0xef],
];
for e in expected.iter() {
assert_eq!(gen.next(), Bytes::copy_from_slice(e))
}
}
}