use crate::error::UVarintError;
pub fn encode_u64(mut value: u64) -> Vec<u8> {
if value == 0 {
return vec![0x00];
}
let mut result = Vec::new();
while value > 0 {
let mut byte = (value & 0x7F) as u8;
value >>= 7;
if value > 0 {
byte |= 0x80; }
result.push(byte);
}
result
}
pub fn encode_u64_into(mut value: u64, buf: &mut [u8]) -> Result<usize, UVarintError> {
if buf.is_empty() {
return Err(UVarintError::BufferTooSmall);
}
if value == 0 {
buf[0] = 0x00;
return Ok(1);
}
let mut i = 0;
while value > 0 {
if i >= buf.len() {
return Err(UVarintError::BufferTooSmall);
}
let mut byte = (value & 0x7F) as u8;
value >>= 7;
if value > 0 {
byte |= 0x80;
}
buf[i] = byte;
i += 1;
}
Ok(i)
}
#[cfg(test)]
mod encode_tests {
use super::*;
#[test]
fn test_encode_single_byte() {
assert_eq!(encode_u64(0), vec![0x00]);
assert_eq!(encode_u64(1), vec![0x01]);
assert_eq!(encode_u64(5), vec![0x05]);
assert_eq!(encode_u64(127), vec![0x7F]); }
#[test]
fn test_encode_two_bytes() {
assert_eq!(encode_u64(128), vec![0x80, 0x01]);
assert_eq!(encode_u64(300), vec![0xAC, 0x02]);
assert_eq!(encode_u64(16_383), vec![0xFF, 0x7F]);
}
#[test]
fn test_encode_step_by_step_300() {
let mut value = 300_u64;
let mut result = Vec::new();
let mut byte = (value & 0x7F) as u8; assert_eq!(byte, 44);
value >>= 7; assert_eq!(value, 2);
byte |= 0x80; assert_eq!(byte, 0xAC);
result.push(byte);
byte = (value & 0x7F) as u8; assert_eq!(byte, 2);
value >>= 7; assert_eq!(value, 0);
assert_eq!(byte, 0x02);
result.push(byte);
assert_eq!(result, vec![0xAC, 0x02]);
assert_eq!(encode_u64(300), vec![0xAC, 0x02]);
}
#[test]
fn test_encode_max_u64() {
let encoded = encode_u64(u64::MAX);
assert_eq!(encoded.len(), 10);
assert_eq!(
encoded,
vec![0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01]
);
}
}