sqlx_postgres/message/
row_description.rs1use sqlx_core::bytes::{Buf, Bytes};
2
3use crate::error::Error;
4use crate::io::BufExt;
5use crate::message::{BackendMessage, BackendMessageFormat};
6use crate::types::Oid;
7
8#[derive(Debug)]
9pub struct RowDescription {
10 pub fields: Vec<Field>,
11}
12
13#[derive(Debug)]
14pub struct Field {
15 pub name: String,
17
18 pub relation_id: Option<Oid>,
21
22 pub relation_attribute_no: Option<i16>,
25
26 pub data_type_id: Oid,
28
29 #[allow(dead_code)]
32 pub data_type_size: i16,
33
34 #[allow(dead_code)]
37 pub type_modifier: i32,
38
39 #[allow(dead_code)]
41 pub format: i16,
42}
43
44impl BackendMessage for RowDescription {
45 const FORMAT: BackendMessageFormat = BackendMessageFormat::RowDescription;
46
47 fn decode_body(mut buf: Bytes) -> Result<Self, Error> {
48 if buf.len() < 2 {
49 return Err(err_protocol!(
50 "expected at least 2 bytes, got {}",
51 buf.len()
52 ));
53 }
54
55 let cnt = buf.get_u16();
56 let mut fields = Vec::with_capacity(cnt as usize);
57
58 for _ in 0..cnt {
59 let name = buf.get_str_nul()?.to_owned();
60
61 if buf.len() < 18 {
62 return Err(err_protocol!(
63 "expected at least 18 bytes after field name {name:?}, got {}",
64 buf.len()
65 ));
66 }
67
68 let relation_id = buf.get_u32();
69 let relation_attribute_no = buf.get_i16();
70 let data_type_id = Oid(buf.get_u32());
71 let data_type_size = buf.get_i16();
72 let type_modifier = buf.get_i32();
73 let format = buf.get_i16();
74
75 fields.push(Field {
76 name,
77 relation_id: if relation_id == 0 {
78 None
79 } else {
80 Some(Oid(relation_id))
81 },
82 relation_attribute_no: if relation_attribute_no == 0 {
83 None
84 } else {
85 Some(relation_attribute_no)
86 },
87 data_type_id,
88 data_type_size,
89 type_modifier,
90 format,
91 })
92 }
93
94 Ok(Self { fields })
95 }
96}
97
98