sqlx_core/mysql/protocol/
packet.rs

1use std::ops::{Deref, DerefMut};
2
3use bytes::Bytes;
4
5use crate::error::Error;
6use crate::io::{Decode, Encode};
7use crate::mysql::protocol::response::{EofPacket, OkPacket};
8use crate::mysql::protocol::Capabilities;
9
10#[derive(Debug)]
11pub struct Packet<T>(pub(crate) T);
12
13impl<'en, 'stream, T> Encode<'stream, (Capabilities, &'stream mut u8)> for Packet<T>
14where
15    T: Encode<'en, Capabilities>,
16{
17    fn encode_with(
18        &self,
19        buf: &mut Vec<u8>,
20        (capabilities, sequence_id): (Capabilities, &'stream mut u8),
21    ) {
22        // reserve space to write the prefixed length
23        let offset = buf.len();
24        buf.extend(&[0_u8; 4]);
25
26        // encode the payload
27        self.0.encode_with(buf, capabilities);
28
29        // determine the length of the encoded payload
30        // and write to our reserved space
31        let len = buf.len() - offset - 4;
32        let header = &mut buf[offset..];
33
34        // FIXME: Support larger packets
35        assert!(len < 0xFF_FF_FF);
36
37        header[..4].copy_from_slice(&(len as u32).to_le_bytes());
38        header[3] = *sequence_id;
39
40        *sequence_id = sequence_id.wrapping_add(1);
41    }
42}
43
44impl Packet<Bytes> {
45    pub(crate) fn decode<'de, T>(self) -> Result<T, Error>
46    where
47        T: Decode<'de, ()>,
48    {
49        self.decode_with(())
50    }
51
52    pub(crate) fn decode_with<'de, T, C>(self, context: C) -> Result<T, Error>
53    where
54        T: Decode<'de, C>,
55    {
56        T::decode_with(self.0, context)
57    }
58
59    pub(crate) fn ok(self) -> Result<OkPacket, Error> {
60        self.decode()
61    }
62
63    pub(crate) fn eof(self, capabilities: Capabilities) -> Result<EofPacket, Error> {
64        if capabilities.contains(Capabilities::DEPRECATE_EOF) {
65            let ok = self.ok()?;
66
67            Ok(EofPacket {
68                warnings: ok.warnings,
69                status: ok.status,
70            })
71        } else {
72            self.decode_with(capabilities)
73        }
74    }
75}
76
77impl Deref for Packet<Bytes> {
78    type Target = Bytes;
79
80    fn deref(&self) -> &Bytes {
81        &self.0
82    }
83}
84
85impl DerefMut for Packet<Bytes> {
86    fn deref_mut(&mut self) -> &mut Bytes {
87        &mut self.0
88    }
89}