bencode inspired tight self describing serialization format
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use super::*;
use atools::prelude::*;
const fn lenleb128(x: u128) -> usize {
    let mut n2 = 0;
    let mut w = x;
    loop {
        w >>= 7;
        if w == 0 {
            n2 += 1;
            break;
        } else {
            n2 += 1;
        }
    }
    n2
}
const fn leb128<const X: u128>() -> [u8; lenleb128(X)] {
    let mut i = 0;
    let mut into: [u8; _] = [0; _];
    let mut w = X;
    loop {
        let n = (w & 127) as u8;
        w >>= 7;
        if w == 0 {
            into[i] = n;
            break;
        } else {
            into[i] = n | 1 << 7;
        }
        i += 1;
    }
    into
}

#[test]
fn test_struct() {
    #[derive(Serialize)]
    struct Test {
        int: u32,
        seq: Vec<&'static str>,
    }

    let test = Test {
        int: 1,
        seq: vec!["hello", "bendncode"],
    };
    let expected = (*b"m")
        .couple(leb128::<2>())
        .couple(*b"s\x03intu")
        .couple(leb128::<1>())
        .couple(*b"s\x03seq")
        .join(b'l')
        .couple(leb128::<2>())
        .join(b's')
        .couple(leb128::<5>())
        .couple(*b"hello")
        .join(b's')
        .couple(leb128::<9>())
        .couple(*b"bendncode");

    assert_eq!(to_bytes(&test).unwrap(), expected);
}

#[test]
fn test_enum() {
    #[derive(Serialize)]
    enum E {
        Unit,
        Newtype(u32),
        Tuple(u32, u32),
        Struct { a: u32 },
    }

    let u = E::Unit;
    let expected = [b'n', b'u', 0];
    assert_eq!(to_bytes(&u).unwrap(), expected);

    // println!("--");

    let n = E::Newtype(51);
    let expected = b"vu"
        .couple(leb128::<1>())
        .join(b'u') // i rather dislike this byte
        .couple(leb128::<51>());

    assert_eq!(to_bytes(&n).unwrap(), expected);
    // println!("--");
    let t = E::Tuple(1, 24151561);
    let expected = b"xu"
        .couple(leb128::<2>())
        .couple(leb128::<2>())
        .join(b'u')
        .couple(leb128::<1>())
        .join(b'u')
        .couple(leb128::<24151561>());
    assert_eq!(to_bytes(&t).unwrap(), expected);
    // println!("--");
    let s = E::Struct { a: 1 };
    let expected = b"yu"
        .couple(leb128::<3>())
        .couple(leb128::<1>())
        .join(b's')
        .couple(leb128::<1>())
        .couple(*b"au")
        .couple(leb128::<1>());
    assert_eq!(to_bytes(&s).unwrap(), expected);
}