sqlx_core_oldapi/postgres/message/
describe.rs

1use crate::io::Encode;
2use crate::postgres::io::PgBufMutExt;
3use crate::postgres::types::Oid;
4
5const DESCRIBE_PORTAL: u8 = b'P';
6const DESCRIBE_STATEMENT: u8 = b'S';
7
8// [Describe] will emit both a [RowDescription] and a [ParameterDescription] message
9
10#[derive(Debug)]
11#[allow(dead_code)]
12pub enum Describe {
13    UnnamedStatement,
14    Statement(Oid),
15
16    UnnamedPortal,
17    Portal(Oid),
18}
19
20impl Encode<'_> for Describe {
21    fn encode_with(&self, buf: &mut Vec<u8>, _: ()) {
22        // 15 bytes for 1-digit statement/portal IDs
23        buf.reserve(20);
24        buf.push(b'D');
25
26        buf.put_length_prefixed(|buf| {
27            match self {
28                // #[likely]
29                Describe::Statement(id) => {
30                    buf.push(DESCRIBE_STATEMENT);
31                    buf.put_statement_name(*id);
32                }
33
34                Describe::UnnamedPortal => {
35                    buf.push(DESCRIBE_PORTAL);
36                    buf.push(0);
37                }
38
39                Describe::UnnamedStatement => {
40                    buf.push(DESCRIBE_STATEMENT);
41                    buf.push(0);
42                }
43
44                Describe::Portal(id) => {
45                    buf.push(DESCRIBE_PORTAL);
46                    buf.put_portal_name(Some(*id));
47                }
48            }
49        });
50    }
51}
52
53#[test]
54fn test_encode_describe_portal() {
55    const EXPECTED: &[u8] = b"D\0\0\0\x0EPsqlx_p_5\0";
56
57    let mut buf = Vec::new();
58    let m = Describe::Portal(Oid(5));
59
60    m.encode(&mut buf);
61
62    assert_eq!(buf, EXPECTED);
63}
64
65#[test]
66fn test_encode_describe_unnamed_portal() {
67    const EXPECTED: &[u8] = b"D\0\0\0\x06P\0";
68
69    let mut buf = Vec::new();
70    let m = Describe::UnnamedPortal;
71
72    m.encode(&mut buf);
73
74    assert_eq!(buf, EXPECTED);
75}
76
77#[test]
78fn test_encode_describe_statement() {
79    const EXPECTED: &[u8] = b"D\0\0\0\x0ESsqlx_s_5\0";
80
81    let mut buf = Vec::new();
82    let m = Describe::Statement(Oid(5));
83
84    m.encode(&mut buf);
85
86    assert_eq!(buf, EXPECTED);
87}
88
89#[test]
90fn test_encode_describe_unnamed_statement() {
91    const EXPECTED: &[u8] = b"D\0\0\0\x06S\0";
92
93    let mut buf = Vec::new();
94    let m = Describe::UnnamedStatement;
95
96    m.encode(&mut buf);
97
98    assert_eq!(buf, EXPECTED);
99}
100
101#[cfg(all(test, not(debug_assertions)))]
102#[bench]
103fn bench_encode_describe_portal(b: &mut test::Bencher) {
104    use test::black_box;
105
106    let mut buf = Vec::with_capacity(128);
107
108    b.iter(|| {
109        buf.clear();
110
111        black_box(Describe::Portal(5)).encode(&mut buf);
112    });
113}
114
115#[cfg(all(test, not(debug_assertions)))]
116#[bench]
117fn bench_encode_describe_unnamed_statement(b: &mut test::Bencher) {
118    use test::black_box;
119
120    let mut buf = Vec::with_capacity(128);
121
122    b.iter(|| {
123        buf.clear();
124
125        black_box(Describe::UnnamedStatement).encode(&mut buf);
126    });
127}