refactor(proto): reuse code in handshakes

This commit is contained in:
Jindřich Moravec 2023-12-23 00:52:53 +01:00
parent 7b2dce4dfb
commit c1744711d3
9 changed files with 111 additions and 88 deletions

View file

@ -0,0 +1,65 @@
use crate::handshake::errors::ClientHandshakeError;
use crate::message::backend::{BackendKeyDataData, BackendMessage, ParameterStatusData};
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})", name = 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);
}
_ => {}
}
}
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.clone().into(),
}),
BackendMessage::BackendKeyData(BackendKeyDataData {
process: response.process_id,
secret: response.secret_key,
}),
]
}
}