vunsigned_varint/
encode.rs1use num_traits::{FromPrimitive, PrimInt, ToPrimitive, Unsigned};
2
3pub fn encode<N>(mut num: N, buffer: &mut [u8]) -> usize
20where
21 N: PrimInt + Unsigned + FromPrimitive + ToPrimitive,
22{
23 let mask = N::from_u8(0x7F).expect("Anything should be able to represent 7 bits");
24 for (index, buffer) in buffer.iter_mut().enumerate() {
25 let byte = (num & mask).to_u8().expect("Mask made sure it fits");
26 num = num >> 7;
27 let byte = if !num.is_zero() { byte | 0x80 } else { byte };
28 *buffer = byte;
29 if num.is_zero() {
30 return index + 1;
31 }
32 }
33 panic!("Buffer size too small")
34}
35
36pub fn encoded_len<N>(num: N) -> usize
45where
46 N: PrimInt + Unsigned,
47{
48 if num.is_zero() {
49 1
50 } else {
51 (core::mem::size_of::<N>() * 8 - num.leading_zeros() as usize).div_ceil(7)
52 }
53}
54
55#[cfg(test)]
56mod test {
57 use crate::encode;
58
59 #[test]
60 fn e1() {
61 let mut buf = [0; 1];
62 encode(0x01_u8, &mut buf);
63 assert_eq!(buf.as_slice(), &[0x01]);
64 }
65
66 #[test]
67 fn e7f() {
68 let mut buf = [0; 1];
69 encode(0x7f_u8, &mut buf);
70 assert_eq!(buf.as_slice(), &[0x7f]);
71 }
72
73 #[test]
74 fn e80() {
75 let mut buf = [0; 2];
76 encode(0x80_u8, &mut buf);
77 assert_eq!(buf.as_slice(), &[0x80, 0x01]);
78 }
79
80 #[test]
81 fn eff() {
82 let mut buf = [0; 2];
83 encode(0xff_u8, &mut buf);
84 assert_eq!(buf.as_slice(), &[0xff, 0x01]);
85 }
86
87 #[test]
88 fn e12c() {
89 let mut buf = [0; 2];
90 encode(0x12c_u16, &mut buf);
91 assert_eq!(buf.as_slice(), &[0xac, 0x02]);
92 }
93
94 #[test]
95 fn e4000() {
96 let mut buf = [0; 3];
97 encode(0x4000_u16, &mut buf);
98 assert_eq!(buf.as_slice(), &[0x80, 0x80, 0x01]);
99 }
100}