diff --git a/proto/src/message/mod.rs b/proto/src/message/mod.rs index 30ae1a3..527e584 100644 --- a/proto/src/message/mod.rs +++ b/proto/src/message/mod.rs @@ -2,3 +2,4 @@ pub mod backend; pub mod frontend; pub mod primitive; pub mod proto_message; +pub mod special; diff --git a/proto/src/message/special.rs b/proto/src/message/special.rs new file mode 100644 index 0000000..166320f --- /dev/null +++ b/proto/src/message/special.rs @@ -0,0 +1,60 @@ +use crate::message::primitive::pgstring::PgString; +use bincode::de::Decoder; +use bincode::enc::Encoder; +use bincode::error::{DecodeError, EncodeError}; +use bincode::{Decode, Encode}; + +#[derive(Debug)] +pub enum SpecialMessage { + CancelRequest(CancelRequestData), + SSLRequest, + StartupMessage(StartupMessageData), +} + +#[derive(Debug, Clone, Encode, Decode)] +pub struct CancelRequestData { + pub pid: i32, + pub secret: i32, +} + +#[derive(Debug, Clone)] +pub struct StartupMessageData { + pub version: i32, + pub params: Vec<(PgString, PgString)>, +} + +impl Encode for StartupMessageData { + fn encode(&self, encoder: &mut E) -> Result<(), EncodeError> { + self.version.encode(encoder)?; + for (key, value) in &self.params { + key.encode(encoder)?; + value.encode(encoder)?; + } + Ok(()) + } +} + +impl Decode for StartupMessageData { + fn decode(decoder: &mut D) -> Result { + let version = i32::decode(decoder)?; + let mut params = Vec::new(); + loop { + let maybe_key = PgString::decode(decoder); + match maybe_key { + Ok(_) => {} + Err(DecodeError::UnexpectedEnd { .. }) => break, + Err(e) => return Err(e), + } + + let maybe_value = PgString::decode(decoder); + match maybe_value { + Ok(_) => {} + Err(DecodeError::UnexpectedEnd { .. }) => break, + Err(e) => return Err(e), + } + + params.push((maybe_key.unwrap(), maybe_value.unwrap())); + } + Ok(StartupMessageData { version, params }) + } +}