69 lines
2.1 KiB
Rust
69 lines
2.1 KiB
Rust
use crate::handshake::errors::ClientHandshakeError;
|
|
use crate::message::backend::{BackendKeyDataData, BackendMessage, ParameterStatusData};
|
|
|
|
#[derive(Debug)]
|
|
pub struct HandshakeResponse {
|
|
pub version: String,
|
|
pub process_id: i32,
|
|
pub secret_key: i32,
|
|
}
|
|
|
|
impl HandshakeResponse {
|
|
pub fn new(name: &str, pid: i32, key: i32) -> Self {
|
|
Self {
|
|
version: format!("16.0 ({name})"),
|
|
process_id: pid,
|
|
secret_key: key,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TryFrom<&[BackendMessage]> for HandshakeResponse {
|
|
type Error = ClientHandshakeError;
|
|
|
|
fn try_from(messages: &[BackendMessage]) -> Result<Self, Self::Error> {
|
|
let mut version = None;
|
|
let mut process_id = None;
|
|
let mut secret_key = None;
|
|
|
|
for message in messages {
|
|
match message {
|
|
BackendMessage::ParameterStatus(data) => {
|
|
if data.name.as_str() == "server_version" {
|
|
version = Some(String::from(data.value.as_str()));
|
|
}
|
|
}
|
|
BackendMessage::BackendKeyData(data) => {
|
|
process_id = Some(data.process);
|
|
secret_key = Some(data.secret);
|
|
}
|
|
// Different messages are ignored during the handshake
|
|
_ => {}
|
|
}
|
|
}
|
|
|
|
match (version, process_id, secret_key) {
|
|
(Some(version), Some(process_id), Some(secret_key)) => Ok(Self {
|
|
version,
|
|
process_id,
|
|
secret_key,
|
|
}),
|
|
_ => Err(ClientHandshakeError::UnexpectedResponse),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<HandshakeResponse> for Vec<BackendMessage> {
|
|
fn from(response: HandshakeResponse) -> Self {
|
|
vec![
|
|
BackendMessage::ParameterStatus(ParameterStatusData {
|
|
name: "server_version".into(),
|
|
value: response.version.into(),
|
|
}),
|
|
BackendMessage::BackendKeyData(BackendKeyDataData {
|
|
process: response.process_id,
|
|
secret: response.secret_key,
|
|
}),
|
|
]
|
|
}
|
|
}
|