pub fn split_number(n: usize) -> Vec<u8> {
let mut bytes = vec![];
let mut i = n;
let chunk = 0b1000_0000;
loop {
let low = i % chunk; i /= chunk;
bytes.push(if bytes.is_empty() { chunk + low } else { low } as u8);
if i == 0 { break; }
}
bytes.reverse();
return bytes;
}
pub fn build_number(bytes: &[u8]) -> (usize, usize) {
let mut i: usize = 0;
let mut e = 0;
let chunk = 0b1000_0000;
for byte in bytes {
e += 1;
i *= chunk as usize;
if byte >= &chunk {
i += (byte - chunk) as usize;
break;
} else {
i += *byte as usize;
}
}
return (i, e);
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn encode_decode() {
let x = 7_289_529_732_981_739_357;
assert_eq!(build_number(&split_number(x)), (x, 9));
}
#[test]
fn rollover() {
let x = 256;
assert_eq!(split_number(x), vec![0b0000_0010, 0b1000_0000])
}
#[test]
fn extra_bytes() {
let x = 42069;
let bytes = split_number(x);
let eat = bytes.len();
let mut extra = bytes.clone();
extra.append(&mut vec![0xBA, 0xDA, 0x55]);
assert_eq!((x, eat), build_number(&bytes));
assert_eq!((x, eat), build_number(&extra));
}
#[test]
fn zero() {
let mut zero = split_number(0);
zero.push(2); assert_eq!(build_number(&zero), (0, 1));
}
}