1
1
#![ allow( missing_docs) ]
2
2
3
- use byteorder:: { BigEndian , ReadBytesExt } ;
3
+ use byteorder:: { BigEndian , ByteOrder , ReadBytesExt } ;
4
4
use bytes:: { Bytes , BytesMut } ;
5
5
use fallible_iterator:: FallibleIterator ;
6
6
use memchr:: memchr;
@@ -11,6 +11,66 @@ use std::str;
11
11
12
12
use crate :: Oid ;
13
13
14
+ pub const PARSE_COMPLETE_TAG : u8 = b'1' ;
15
+ pub const BIND_COMPLETE_TAG : u8 = b'2' ;
16
+ pub const CLOSE_COMPLETE_TAG : u8 = b'3' ;
17
+ pub const NOTIFICATION_RESPONSE_TAG : u8 = b'A' ;
18
+ pub const COPY_DONE_TAG : u8 = b'c' ;
19
+ pub const COMMAND_COMPLETE_TAG : u8 = b'C' ;
20
+ pub const COPY_DATA_TAG : u8 = b'd' ;
21
+ pub const DATA_ROW_TAG : u8 = b'D' ;
22
+ pub const ERROR_RESPONSE_TAG : u8 = b'E' ;
23
+ pub const COPY_IN_RESPONSE_TAG : u8 = b'G' ;
24
+ pub const COPY_OUT_RESPONSE_TAG : u8 = b'H' ;
25
+ pub const EMPTY_QUERY_RESPONSE_TAG : u8 = b'I' ;
26
+ pub const BACKEND_KEY_DATA_TAG : u8 = b'K' ;
27
+ pub const NO_DATA_TAG : u8 = b'n' ;
28
+ pub const NOTICE_RESPONSE_TAG : u8 = b'N' ;
29
+ pub const AUTHENTICATION_TAG : u8 = b'R' ;
30
+ pub const PORTAL_SUSPENDED_TAG : u8 = b's' ;
31
+ pub const PARAMETER_STATUS_TAG : u8 = b'S' ;
32
+ pub const PARAMETER_DESCRIPTION_TAG : u8 = b't' ;
33
+ pub const ROW_DESCRIPTION_TAG : u8 = b'T' ;
34
+ pub const READY_FOR_QUERY_TAG : u8 = b'Z' ;
35
+
36
+ #[ derive( Debug , Copy , Clone ) ]
37
+ pub struct Header {
38
+ tag : u8 ,
39
+ len : i32 ,
40
+ }
41
+
42
+ #[ allow( clippy:: len_without_is_empty) ]
43
+ impl Header {
44
+ #[ inline]
45
+ pub fn parse ( buf : & [ u8 ] ) -> io:: Result < Option < Header > > {
46
+ if buf. len ( ) < 5 {
47
+ return Ok ( None ) ;
48
+ }
49
+
50
+ let tag = buf[ 0 ] ;
51
+ let len = BigEndian :: read_i32 ( & buf[ 1 ..] ) ;
52
+
53
+ if len < 4 {
54
+ return Err ( io:: Error :: new (
55
+ io:: ErrorKind :: InvalidData ,
56
+ "invalid message length" ,
57
+ ) ) ;
58
+ }
59
+
60
+ Ok ( Some ( Header { tag, len } ) )
61
+ }
62
+
63
+ #[ inline]
64
+ pub fn tag ( self ) -> u8 {
65
+ self . tag
66
+ }
67
+
68
+ #[ inline]
69
+ pub fn len ( self ) -> i32 {
70
+ self . len
71
+ }
72
+ }
73
+
14
74
/// An enum representing Postgres backend messages.
15
75
pub enum Message {
16
76
AuthenticationCleartextPassword ,
@@ -80,10 +140,10 @@ impl Message {
80
140
} ;
81
141
82
142
let message = match tag {
83
- b'1' => Message :: ParseComplete ,
84
- b'2' => Message :: BindComplete ,
85
- b'3' => Message :: CloseComplete ,
86
- b'A' => {
143
+ PARSE_COMPLETE_TAG => Message :: ParseComplete ,
144
+ BIND_COMPLETE_TAG => Message :: BindComplete ,
145
+ CLOSE_COMPLETE_TAG => Message :: CloseComplete ,
146
+ NOTIFICATION_RESPONSE_TAG => {
87
147
let process_id = buf. read_i32 :: < BigEndian > ( ) ?;
88
148
let channel = buf. read_cstr ( ) ?;
89
149
let message = buf. read_cstr ( ) ?;
@@ -93,25 +153,25 @@ impl Message {
93
153
message,
94
154
} )
95
155
}
96
- b'c' => Message :: CopyDone ,
97
- b'C' => {
156
+ COPY_DONE_TAG => Message :: CopyDone ,
157
+ COMMAND_COMPLETE_TAG => {
98
158
let tag = buf. read_cstr ( ) ?;
99
159
Message :: CommandComplete ( CommandCompleteBody { tag } )
100
160
}
101
- b'd' => {
161
+ COPY_DATA_TAG => {
102
162
let storage = buf. read_all ( ) ;
103
163
Message :: CopyData ( CopyDataBody { storage } )
104
164
}
105
- b'D' => {
165
+ DATA_ROW_TAG => {
106
166
let len = buf. read_u16 :: < BigEndian > ( ) ?;
107
167
let storage = buf. read_all ( ) ;
108
168
Message :: DataRow ( DataRowBody { storage, len } )
109
169
}
110
- b'E' => {
170
+ ERROR_RESPONSE_TAG => {
111
171
let storage = buf. read_all ( ) ;
112
172
Message :: ErrorResponse ( ErrorResponseBody { storage } )
113
173
}
114
- b'G' => {
174
+ COPY_IN_RESPONSE_TAG => {
115
175
let format = buf. read_u8 ( ) ?;
116
176
let len = buf. read_u16 :: < BigEndian > ( ) ?;
117
177
let storage = buf. read_all ( ) ;
@@ -121,7 +181,7 @@ impl Message {
121
181
storage,
122
182
} )
123
183
}
124
- b'H' => {
184
+ COPY_OUT_RESPONSE_TAG => {
125
185
let format = buf. read_u8 ( ) ?;
126
186
let len = buf. read_u16 :: < BigEndian > ( ) ?;
127
187
let storage = buf. read_all ( ) ;
@@ -131,21 +191,21 @@ impl Message {
131
191
storage,
132
192
} )
133
193
}
134
- b'I' => Message :: EmptyQueryResponse ,
135
- b'K' => {
194
+ EMPTY_QUERY_RESPONSE_TAG => Message :: EmptyQueryResponse ,
195
+ BACKEND_KEY_DATA_TAG => {
136
196
let process_id = buf. read_i32 :: < BigEndian > ( ) ?;
137
197
let secret_key = buf. read_i32 :: < BigEndian > ( ) ?;
138
198
Message :: BackendKeyData ( BackendKeyDataBody {
139
199
process_id,
140
200
secret_key,
141
201
} )
142
202
}
143
- b'n' => Message :: NoData ,
144
- b'N' => {
203
+ NO_DATA_TAG => Message :: NoData ,
204
+ NOTICE_RESPONSE_TAG => {
145
205
let storage = buf. read_all ( ) ;
146
206
Message :: NoticeResponse ( NoticeResponseBody { storage } )
147
207
}
148
- b'R' => match buf. read_i32 :: < BigEndian > ( ) ? {
208
+ AUTHENTICATION_TAG => match buf. read_i32 :: < BigEndian > ( ) ? {
149
209
0 => Message :: AuthenticationOk ,
150
210
2 => Message :: AuthenticationKerberosV5 ,
151
211
3 => Message :: AuthenticationCleartextPassword ,
@@ -180,23 +240,23 @@ impl Message {
180
240
) ) ;
181
241
}
182
242
} ,
183
- b's' => Message :: PortalSuspended ,
184
- b'S' => {
243
+ PORTAL_SUSPENDED_TAG => Message :: PortalSuspended ,
244
+ PARAMETER_STATUS_TAG => {
185
245
let name = buf. read_cstr ( ) ?;
186
246
let value = buf. read_cstr ( ) ?;
187
247
Message :: ParameterStatus ( ParameterStatusBody { name, value } )
188
248
}
189
- b't' => {
249
+ PARAMETER_DESCRIPTION_TAG => {
190
250
let len = buf. read_u16 :: < BigEndian > ( ) ?;
191
251
let storage = buf. read_all ( ) ;
192
252
Message :: ParameterDescription ( ParameterDescriptionBody { storage, len } )
193
253
}
194
- b'T' => {
254
+ ROW_DESCRIPTION_TAG => {
195
255
let len = buf. read_u16 :: < BigEndian > ( ) ?;
196
256
let storage = buf. read_all ( ) ;
197
257
Message :: RowDescription ( RowDescriptionBody { storage, len } )
198
258
}
199
- b'Z' => {
259
+ READY_FOR_QUERY_TAG => {
200
260
let status = buf. read_u8 ( ) ?;
201
261
Message :: ReadyForQuery ( ReadyForQueryBody { status } )
202
262
}
0 commit comments