use byteorder::LittleEndian;
use crate::io::BufMut;
use crate::mysql::io::BufMutExt;
use crate::mysql::protocol::{AuthPlugin, Capabilities, Encode};
#[derive(Debug)]
pub struct HandshakeResponse<'a> {
pub max_packet_size: u32,
pub client_collation: u8,
pub username: &'a str,
pub database: Option<&'a str>,
pub auth_plugin: &'a AuthPlugin,
pub auth_response: &'a [u8],
}
impl Encode for HandshakeResponse<'_> {
fn encode(&self, buf: &mut Vec<u8>, capabilities: Capabilities) {
buf.put_u32::<LittleEndian>(capabilities.bits() as u32);
buf.put_u32::<LittleEndian>(self.max_packet_size);
buf.put_u8(self.client_collation);
buf.advance(19);
if capabilities.contains(Capabilities::MYSQL) {
buf.advance(4);
} else {
buf.put_u32::<LittleEndian>((capabilities.bits() >> 32) as u32);
}
buf.put_str_nul(self.username);
if capabilities.contains(Capabilities::PLUGIN_AUTH_LENENC_DATA) {
buf.put_bytes_lenenc::<LittleEndian>(self.auth_response);
} else if capabilities.contains(Capabilities::SECURE_CONNECTION) {
let auth_response = self.auth_response;
buf.put_u8(auth_response.len() as u8);
buf.put_bytes(auth_response);
} else {
buf.put_u8(0);
}
if capabilities.contains(Capabilities::CONNECT_WITH_DB) {
if let Some(database) = self.database {
buf.put_str_nul(database);
}
}
if capabilities.contains(Capabilities::PLUGIN_AUTH) {
buf.put_str_nul(self.auth_plugin.as_str());
}
}
}