use crate::Serializable;
use std::convert::TryInto;
pub type VarInt = usize;
impl Serializable<VarInt> for VarInt {
fn deserialize(mut cur: &mut [u8]) -> (VarInt, &mut [u8]) {
let (first_byte, _cur) = cur.split_at_mut(1);
cur = _cur;
let num = match first_byte[0] {
0xFF => {
let (bytes, _cur) = cur.split_at_mut(8);
cur = _cur;
u64::from_le_bytes((*bytes).try_into().unwrap()) as usize
}
0xFE => {
let (bytes, _cur) = cur.split_at_mut(4);
cur = _cur;
u32::from_le_bytes((*bytes).try_into().unwrap()) as usize
}
0xFC => {
let (bytes, _cur) = cur.split_at_mut(2);
cur = _cur;
u16::from_le_bytes((*bytes).try_into().unwrap()) as usize
}
_ => first_byte[0] as usize,
};
return (num, cur);
}
fn serialize(&self) -> Vec<u8> {
let mut v = vec![];
return if *self < 0xFD {
v.push(*self as u8);
v
} else if *self < 0xFFFF {
v.push(0xFD);
v.extend((*self as u16).to_le_bytes().to_vec());
v
} else if *self < 0xFFFFFFFF {
v.push(0xFE);
v.extend((*self as u32).to_le_bytes().to_vec());
v
} else {
v.push(0xFF);
v.extend((*self as u64).to_le_bytes().to_vec());
v
};
}
}
#[cfg(test)]
pub mod test {
use super::*;
#[test]
fn serialize_int_test() {
assert_eq!(VarInt::serialize(&10), vec![10u8]);
assert_eq!(VarInt::serialize(&0xFC), vec![0xFCu8]);
assert_eq!(VarInt::serialize(&0xFD), vec![0xFDu8, 0xFD, 0]);
assert_eq!(VarInt::serialize(&0xFFF), vec![0xFDu8, 0xFF, 0xF]);
assert_eq!(
VarInt::serialize(&0xF0F0F0F),
vec![0xFEu8, 0xF, 0xF, 0xF, 0xF]
);
assert_eq!(
VarInt::serialize(&0xF0F0F0F0F0E0),
vec![0xFFu8, 0xE0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0, 0]
);
}
}