zero_postgres/protocol/backend/
extended.rs

1//! Extended query protocol backend messages.
2
3use zerocopy::{FromBytes, Immutable, KnownLayout};
4
5use crate::error::{Error, Result};
6use crate::protocol::codec::read_u32;
7use crate::protocol::types::Oid;
8use zerocopy::byteorder::big_endian::U16 as U16BE;
9
10/// ParseComplete message - statement parsing completed.
11#[derive(Debug, Clone, Copy)]
12pub struct ParseComplete;
13
14impl ParseComplete {
15    /// Parse a ParseComplete message from payload bytes.
16    pub fn parse(_payload: &[u8]) -> Result<Self> {
17        Ok(Self)
18    }
19}
20
21/// BindComplete message - parameter binding completed.
22#[derive(Debug, Clone, Copy)]
23pub struct BindComplete;
24
25impl BindComplete {
26    /// Parse a BindComplete message from payload bytes.
27    pub fn parse(_payload: &[u8]) -> Result<Self> {
28        Ok(Self)
29    }
30}
31
32/// CloseComplete message - statement/portal close completed.
33#[derive(Debug, Clone, Copy)]
34pub struct CloseComplete;
35
36impl CloseComplete {
37    /// Parse a CloseComplete message from payload bytes.
38    pub fn parse(_payload: &[u8]) -> Result<Self> {
39        Ok(Self)
40    }
41}
42
43/// NoData message - query returns no data.
44#[derive(Debug, Clone, Copy)]
45pub struct NoData;
46
47impl NoData {
48    /// Parse a NoData message from payload bytes.
49    pub fn parse(_payload: &[u8]) -> Result<Self> {
50        Ok(Self)
51    }
52}
53
54/// PortalSuspended message - row limit reached in Execute.
55#[derive(Debug, Clone, Copy)]
56pub struct PortalSuspended;
57
58impl PortalSuspended {
59    /// Parse a PortalSuspended message from payload bytes.
60    pub fn parse(_payload: &[u8]) -> Result<Self> {
61        Ok(Self)
62    }
63}
64
65/// ParameterDescription message header.
66#[derive(Debug, Clone, Copy, FromBytes, KnownLayout, Immutable)]
67#[repr(C, packed)]
68pub struct ParameterDescriptionHead {
69    /// Number of parameters
70    pub num_params: U16BE,
71}
72
73/// ParameterDescription message - describes parameters for a prepared statement.
74#[derive(Debug, Clone)]
75pub struct ParameterDescription {
76    /// Parameter type OIDs
77    param_oids: Vec<Oid>,
78}
79
80impl ParameterDescription {
81    /// Parse a ParameterDescription message from payload bytes.
82    pub fn parse(payload: &[u8]) -> Result<Self> {
83        let head = ParameterDescriptionHead::ref_from_bytes(&payload[..2])
84            .map_err(|e| Error::Protocol(format!("ParameterDescription header: {e:?}")))?;
85
86        let num_params = head.num_params.get() as usize;
87        let mut param_oids = Vec::with_capacity(num_params);
88        let mut data = &payload[2..];
89
90        for _ in 0..num_params {
91            let (oid, rest) = read_u32(data)?;
92            param_oids.push(oid);
93            data = rest;
94        }
95
96        Ok(Self { param_oids })
97    }
98
99    /// Get the number of parameters.
100    pub fn len(&self) -> usize {
101        self.param_oids.len()
102    }
103
104    /// Check if there are no parameters.
105    pub fn is_empty(&self) -> bool {
106        self.param_oids.is_empty()
107    }
108
109    /// Get parameter type OIDs.
110    pub fn oids(&self) -> &[Oid] {
111        &self.param_oids
112    }
113
114    /// Iterate over parameter type OIDs.
115    pub fn iter(&self) -> impl Iterator<Item = &Oid> {
116        self.param_oids.iter()
117    }
118}