diff --git a/sqlx-postgres-protocol/src/describe.rs b/sqlx-postgres-protocol/src/describe.rs new file mode 100644 index 00000000..afc25cd0 --- /dev/null +++ b/sqlx-postgres-protocol/src/describe.rs @@ -0,0 +1,64 @@ +use crate::Encode; +use std::io; + +#[derive(Debug)] +pub enum DescribeKind { + Portal, + PreparedStatement, +} + +#[derive(Debug)] +pub struct Describe<'a> { + kind: DescribeKind, + name: &'a str, +} + +impl<'a> Describe<'a> { + pub fn new(kind: DescribeKind, name: &'a str) -> Self { + Self { kind, name } + } +} + +impl<'a> Encode for Describe<'a> { + fn encode(&self, buf: &mut Vec) -> io::Result<()> { + buf.push(b'D'); + + let len = 4 + self.name.len() + 1 + 4; + buf.extend_from_slice(&(len as i32).to_be_bytes()); + + match &self.kind { + DescribeKind::Portal => buf.push(b'P'), + DescribeKind::PreparedStatement => buf.push(b'S'), + }; + + buf.extend_from_slice(self.name.as_bytes()); + buf.push(b'\0'); + + Ok(()) + } +} + +#[cfg(test)] +mod test { + use super::{Describe, DescribeKind}; + use crate::Encode; + use std::io; + + #[test] + fn it_encodes_describe_portal() -> io::Result<()> { + let mut buf = vec![]; + Describe::new(DescribeKind::Portal, "ABC123").encode(&mut buf)?; + assert_eq!(&buf, b"D\x00\x00\x00\x0fPABC123\x00"); + + Ok(()) + } + + #[test] + fn it_encodes_describe_statement() -> io::Result<()> { + let mut buf = vec![]; + Describe::new(DescribeKind::PreparedStatement, "95 apples").encode(&mut buf)?; + assert_eq!(&buf, b"D\x00\x00\x00\x12S95 apples\x00"); + + Ok(()) + } +} \ No newline at end of file diff --git a/sqlx-postgres-protocol/src/lib.rs b/sqlx-postgres-protocol/src/lib.rs index 9ee84807..21156e12 100644 --- a/sqlx-postgres-protocol/src/lib.rs +++ b/sqlx-postgres-protocol/src/lib.rs @@ -6,6 +6,7 @@ pub mod bind; mod command_complete; mod data_row; mod decode; +mod describe; mod encode; mod execute; mod message; @@ -28,6 +29,7 @@ pub use self::{ command_complete::CommandComplete, data_row::DataRow, decode::Decode, + describe::{Describe, DescribeKind}, encode::Encode, execute::Execute, message::Message,