sqlx_postgres/message/
describe.rs

1use crate::io::{PgBufMutExt, PortalId, StatementId};
2use crate::message::{FrontendMessage, FrontendMessageFormat};
3use sqlx_core::Error;
4use std::num::Saturating;
5
6const DESCRIBE_PORTAL: u8 = b'P';
7const DESCRIBE_STATEMENT: u8 = b'S';
8
9/// Note: will emit both a RowDescription and a ParameterDescription message
10#[derive(Debug)]
11#[allow(dead_code)]
12pub enum Describe {
13    Statement(StatementId),
14    Portal(PortalId),
15}
16
17impl FrontendMessage for Describe {
18    const FORMAT: FrontendMessageFormat = FrontendMessageFormat::Describe;
19
20    fn body_size_hint(&self) -> Saturating<usize> {
21        // Either `DESCRIBE_PORTAL` or `DESCRIBE_STATEMENT`
22        let mut size = Saturating(1);
23
24        match self {
25            Describe::Statement(id) => size += id.name_len(),
26            Describe::Portal(id) => size += id.name_len(),
27        }
28
29        size
30    }
31
32    fn encode_body(&self, buf: &mut Vec<u8>) -> Result<(), Error> {
33        match self {
34            // #[likely]
35            Describe::Statement(id) => {
36                buf.push(DESCRIBE_STATEMENT);
37                buf.put_statement_name(*id);
38            }
39
40            Describe::Portal(id) => {
41                buf.push(DESCRIBE_PORTAL);
42                buf.put_portal_name(*id);
43            }
44        }
45
46        Ok(())
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use crate::message::FrontendMessage;
53
54    use super::{Describe, PortalId, StatementId};
55
56    #[test]
57    fn test_encode_describe_portal() {
58        const EXPECTED: &[u8] = b"D\0\0\0\x17Psqlx_p_1234567890\0";
59
60        let mut buf = Vec::new();
61        let m = Describe::Portal(PortalId::TEST_VAL);
62
63        m.encode_msg(&mut buf).unwrap();
64
65        assert_eq!(buf, EXPECTED);
66    }
67
68    #[test]
69    fn test_encode_describe_unnamed_portal() {
70        const EXPECTED: &[u8] = b"D\0\0\0\x06P\0";
71
72        let mut buf = Vec::new();
73        let m = Describe::Portal(PortalId::UNNAMED);
74
75        m.encode_msg(&mut buf).unwrap();
76
77        assert_eq!(buf, EXPECTED);
78    }
79
80    #[test]
81    fn test_encode_describe_statement() {
82        const EXPECTED: &[u8] = b"D\0\0\0\x17Ssqlx_s_1234567890\0";
83
84        let mut buf = Vec::new();
85        let m = Describe::Statement(StatementId::TEST_VAL);
86
87        m.encode_msg(&mut buf).unwrap();
88
89        assert_eq!(buf, EXPECTED);
90    }
91
92    #[test]
93    fn test_encode_describe_unnamed_statement() {
94        const EXPECTED: &[u8] = b"D\0\0\0\x06S\0";
95
96        let mut buf = Vec::new();
97        let m = Describe::Statement(StatementId::UNNAMED);
98
99        m.encode_msg(&mut buf).unwrap();
100
101        assert_eq!(buf, EXPECTED);
102    }
103}