sqlx_core/mysql/protocol/
packet.rs1use 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 let offset = buf.len();
24 buf.extend(&[0_u8; 4]);
25
26 self.0.encode_with(buf, capabilities);
28
29 let len = buf.len() - offset - 4;
32 let header = &mut buf[offset..];
33
34 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}