sqlx_mysql/io/
buf_mut.rs

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use bytes::BufMut;

pub trait MySqlBufMutExt: BufMut {
    fn put_uint_lenenc(&mut self, v: u64);

    fn put_str_lenenc(&mut self, v: &str);

    fn put_bytes_lenenc(&mut self, v: &[u8]);
}

impl MySqlBufMutExt for Vec<u8> {
    fn put_uint_lenenc(&mut self, v: u64) {
        // https://dev.mysql.com/doc/internals/en/integer.html
        // https://mariadb.com/kb/en/library/protocol-data-types/#length-encoded-integers

        let encoded_le = v.to_le_bytes();

        match v {
            0..=250 => self.push(encoded_le[0]),
            251..=0xFF_FF => {
                self.push(0xfc);
                self.extend_from_slice(&encoded_le[..2]);
            }
            0x1_00_00..=0xFF_FF_FF => {
                self.push(0xfd);
                self.extend_from_slice(&encoded_le[..3]);
            }
            _ => {
                self.push(0xfe);
                self.extend_from_slice(&encoded_le);
            }
        }
    }

    fn put_str_lenenc(&mut self, v: &str) {
        self.put_bytes_lenenc(v.as_bytes());
    }

    fn put_bytes_lenenc(&mut self, v: &[u8]) {
        self.put_uint_lenenc(v.len() as u64);
        self.extend(v);
    }
}

#[test]
fn test_encodes_int_lenenc_u8() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(0xFA as u64);

    assert_eq!(&buf[..], b"\xFA");
}

#[test]
fn test_encodes_int_lenenc_u16() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(std::u16::MAX as u64);

    assert_eq!(&buf[..], b"\xFC\xFF\xFF");
}

#[test]
fn test_encodes_int_lenenc_u24() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(0xFF_FF_FF as u64);

    assert_eq!(&buf[..], b"\xFD\xFF\xFF\xFF");
}

#[test]
fn test_encodes_int_lenenc_u64() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(std::u64::MAX);

    assert_eq!(&buf[..], b"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF");
}

#[test]
fn test_encodes_int_lenenc_fb() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(0xFB as u64);

    assert_eq!(&buf[..], b"\xFC\xFB\x00");
}

#[test]
fn test_encodes_int_lenenc_fc() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(0xFC as u64);

    assert_eq!(&buf[..], b"\xFC\xFC\x00");
}

#[test]
fn test_encodes_int_lenenc_fd() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(0xFD as u64);

    assert_eq!(&buf[..], b"\xFC\xFD\x00");
}

#[test]
fn test_encodes_int_lenenc_fe() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(0xFE as u64);

    assert_eq!(&buf[..], b"\xFC\xFE\x00");
}

#[test]
fn test_encodes_int_lenenc_ff() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_uint_lenenc(0xFF as u64);

    assert_eq!(&buf[..], b"\xFC\xFF\x00");
}

#[test]
fn test_encodes_string_lenenc() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_str_lenenc("random_string");

    assert_eq!(&buf[..], b"\x0Drandom_string");
}

#[test]
fn test_encodes_byte_lenenc() {
    let mut buf = Vec::with_capacity(1024);
    buf.put_bytes_lenenc(b"random_string");

    assert_eq!(&buf[..], b"\x0Drandom_string");
}