feat(proto): add frontend messages

This commit is contained in:
Jindřich Moravec 2023-12-11 16:43:46 +01:00
parent 3512067c4e
commit ee2742ea03
2 changed files with 69 additions and 0 deletions

View file

@ -0,0 +1,68 @@
use crate::message::primitive::data::MessageData;
use crate::message::primitive::pgstring::PgString;
use crate::message::proto_message::ProtoMessage;
use bincode::{Decode, Encode};
#[derive(Debug)]
pub enum FrontendMessage {
Query(QueryData),
Terminate,
}
impl ProtoMessage for FrontendMessage {
fn variant(&self) -> u8 {
match self {
FrontendMessage::Query(_) => b'Q',
FrontendMessage::Terminate => b'X',
}
}
fn serialize(&self) -> anyhow::Result<Vec<u8>> {
match self {
FrontendMessage::Query(data) => data.serialize(),
FrontendMessage::Terminate => Ok(Vec::with_capacity(0)),
}
}
fn deserialize(variant: u8, data: &[u8]) -> anyhow::Result<Self> {
match variant {
b'Q' => Ok(FrontendMessage::Query(QueryData::deserialize(data)?)),
b'X' => Ok(FrontendMessage::Terminate),
v => Err(anyhow::anyhow!("Unknown frontend message variant: {v}")),
}
}
}
#[derive(Debug, Clone, Encode, Decode)]
pub struct QueryData {
pub query: PgString,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_symmetric_query() {
let frontend = FrontendMessage::Query(QueryData {
query: PgString::from("SELECT * FROM foo WHERE bar = $1"),
});
let raw = frontend.serialize().unwrap();
let variant = frontend.variant();
let message = FrontendMessage::deserialize(variant, &raw).unwrap();
assert!(
matches!(message, FrontendMessage::Query(QueryData { query }) if query.as_str() == "SELECT * FROM foo WHERE bar = $1")
);
}
#[test]
fn test_symmetric_terminate() {
let frontend = FrontendMessage::Terminate;
let raw = frontend.serialize().unwrap();
let variant = frontend.variant();
let message = FrontendMessage::deserialize(variant, &raw).unwrap();
assert!(matches!(message, FrontendMessage::Terminate));
}
}