/src/thrift/lib/rs/src/protocol/mod.rs
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | |
18 | | //! Types used to send and receive primitives between a Thrift client and server. |
19 | | //! |
20 | | //! # Examples |
21 | | //! |
22 | | //! Create and use a `TInputProtocol`. |
23 | | //! |
24 | | //! ```no_run |
25 | | //! use thrift::protocol::{TBinaryInputProtocol, TInputProtocol}; |
26 | | //! use thrift::transport::TTcpChannel; |
27 | | //! |
28 | | //! // create the I/O channel |
29 | | //! let mut channel = TTcpChannel::new(); |
30 | | //! channel.open("127.0.0.1:9090").unwrap(); |
31 | | //! |
32 | | //! // create the protocol to decode bytes into types |
33 | | //! let mut protocol = TBinaryInputProtocol::new(channel, true); |
34 | | //! |
35 | | //! // read types from the wire |
36 | | //! let field_identifier = protocol.read_field_begin().unwrap(); |
37 | | //! let field_contents = protocol.read_string().unwrap(); |
38 | | //! let field_end = protocol.read_field_end().unwrap(); |
39 | | //! ``` |
40 | | //! |
41 | | //! Create and use a `TOutputProtocol`. |
42 | | //! |
43 | | //! ```no_run |
44 | | //! use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType}; |
45 | | //! use thrift::transport::TTcpChannel; |
46 | | //! |
47 | | //! // create the I/O channel |
48 | | //! let mut channel = TTcpChannel::new(); |
49 | | //! channel.open("127.0.0.1:9090").unwrap(); |
50 | | //! |
51 | | //! // create the protocol to encode types into bytes |
52 | | //! let mut protocol = TBinaryOutputProtocol::new(channel, true); |
53 | | //! |
54 | | //! // write types |
55 | | //! protocol.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap(); |
56 | | //! protocol.write_string("foo").unwrap(); |
57 | | //! protocol.write_field_end().unwrap(); |
58 | | //! ``` |
59 | | |
60 | | use std::convert::{From, TryFrom}; |
61 | | use std::fmt; |
62 | | use std::fmt::{Display, Formatter}; |
63 | | |
64 | | use crate::transport::{TReadTransport, TWriteTransport}; |
65 | | use crate::{ProtocolError, ProtocolErrorKind, TConfiguration}; |
66 | | |
67 | | #[cfg(test)] |
68 | | macro_rules! assert_eq_written_bytes { |
69 | | ($o_prot:ident, $expected_bytes:ident) => {{ |
70 | | assert_eq!($o_prot.transport.write_bytes(), &$expected_bytes); |
71 | | }}; |
72 | | } |
73 | | |
74 | | // FIXME: should take both read and write |
75 | | #[cfg(test)] |
76 | | macro_rules! copy_write_buffer_to_read_buffer { |
77 | | ($o_prot:ident) => {{ |
78 | | $o_prot.transport.copy_write_buffer_to_read_buffer(); |
79 | | }}; |
80 | | } |
81 | | |
82 | | #[cfg(test)] |
83 | | macro_rules! set_readable_bytes { |
84 | | ($i_prot:ident, $bytes:expr) => { |
85 | | $i_prot.transport.set_readable_bytes($bytes); |
86 | | }; |
87 | | } |
88 | | |
89 | | mod binary; |
90 | | mod compact; |
91 | | mod multiplexed; |
92 | | mod stored; |
93 | | |
94 | | pub use self::binary::{ |
95 | | TBinaryInputProtocol, TBinaryInputProtocolFactory, TBinaryOutputProtocol, |
96 | | TBinaryOutputProtocolFactory, |
97 | | }; |
98 | | pub use self::compact::{ |
99 | | TCompactInputProtocol, TCompactInputProtocolFactory, TCompactOutputProtocol, |
100 | | TCompactOutputProtocolFactory, |
101 | | }; |
102 | | pub use self::multiplexed::TMultiplexedOutputProtocol; |
103 | | pub use self::stored::TStoredInputProtocol; |
104 | | |
105 | | /// Reads and writes the struct to Thrift protocols. |
106 | | /// |
107 | | /// It is implemented in generated code for Thrift `struct`, `union`, and `enum` types. |
108 | | pub trait TSerializable: Sized { |
109 | | fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> crate::Result<Self>; |
110 | | fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> crate::Result<()>; |
111 | | } |
112 | | |
113 | | // Default maximum depth to which `TInputProtocol::skip` will skip a Thrift |
114 | | // field. A default is necessary because Thrift structs or collections may |
115 | | // contain nested structs and collections, which could result in indefinite |
116 | | // recursion. |
117 | | const MAXIMUM_SKIP_DEPTH: i8 = 64; |
118 | | |
119 | | /// Converts a stream of bytes into Thrift identifiers, primitives, |
120 | | /// containers, or structs. |
121 | | /// |
122 | | /// This trait does not deal with higher-level Thrift concepts like structs or |
123 | | /// exceptions - only with primitives and message or container boundaries. Once |
124 | | /// bytes are read they are deserialized and an identifier (for example |
125 | | /// `TMessageIdentifier`) or a primitive is returned. |
126 | | /// |
127 | | /// All methods return a `thrift::Result`. If an `Err` is returned the protocol |
128 | | /// instance and its underlying transport should be terminated. |
129 | | /// |
130 | | /// # Examples |
131 | | /// |
132 | | /// Create and use a `TInputProtocol` |
133 | | /// |
134 | | /// ```no_run |
135 | | /// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol}; |
136 | | /// use thrift::transport::TTcpChannel; |
137 | | /// |
138 | | /// let mut channel = TTcpChannel::new(); |
139 | | /// channel.open("127.0.0.1:9090").unwrap(); |
140 | | /// |
141 | | /// let mut protocol = TBinaryInputProtocol::new(channel, true); |
142 | | /// |
143 | | /// let field_identifier = protocol.read_field_begin().unwrap(); |
144 | | /// let field_contents = protocol.read_string().unwrap(); |
145 | | /// let field_end = protocol.read_field_end().unwrap(); |
146 | | /// ``` |
147 | | pub trait TInputProtocol { |
148 | | /// Read the beginning of a Thrift message. |
149 | | fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier>; |
150 | | /// Read the end of a Thrift message. |
151 | | fn read_message_end(&mut self) -> crate::Result<()>; |
152 | | /// Read the beginning of a Thrift struct. |
153 | | fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>>; |
154 | | /// Read the end of a Thrift struct. |
155 | | fn read_struct_end(&mut self) -> crate::Result<()>; |
156 | | /// Read the beginning of a Thrift struct field. |
157 | | fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier>; |
158 | | /// Read the end of a Thrift struct field. |
159 | | fn read_field_end(&mut self) -> crate::Result<()>; |
160 | | /// Read a bool. |
161 | | fn read_bool(&mut self) -> crate::Result<bool>; |
162 | | /// Read a fixed-length byte array. |
163 | | fn read_bytes(&mut self) -> crate::Result<Vec<u8>>; |
164 | | /// Read a word. |
165 | | fn read_i8(&mut self) -> crate::Result<i8>; |
166 | | /// Read a 16-bit signed integer. |
167 | | fn read_i16(&mut self) -> crate::Result<i16>; |
168 | | /// Read a 32-bit signed integer. |
169 | | fn read_i32(&mut self) -> crate::Result<i32>; |
170 | | /// Read a 64-bit signed integer. |
171 | | fn read_i64(&mut self) -> crate::Result<i64>; |
172 | | /// Read a 64-bit float. |
173 | | fn read_double(&mut self) -> crate::Result<f64>; |
174 | | /// Read a UUID. |
175 | | fn read_uuid(&mut self) -> crate::Result<uuid::Uuid>; |
176 | | /// Read a fixed-length string (not null terminated). |
177 | | fn read_string(&mut self) -> crate::Result<String>; |
178 | | /// Read the beginning of a list. |
179 | | fn read_list_begin(&mut self) -> crate::Result<TListIdentifier>; |
180 | | /// Read the end of a list. |
181 | | fn read_list_end(&mut self) -> crate::Result<()>; |
182 | | /// Read the beginning of a set. |
183 | | fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier>; |
184 | | /// Read the end of a set. |
185 | | fn read_set_end(&mut self) -> crate::Result<()>; |
186 | | /// Read the beginning of a map. |
187 | | fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier>; |
188 | | /// Read the end of a map. |
189 | | fn read_map_end(&mut self) -> crate::Result<()>; |
190 | | /// Skip a field with type `field_type` recursively until the default |
191 | | /// maximum skip depth is reached. |
192 | 5.45M | fn skip(&mut self, field_type: TType) -> crate::Result<()> { |
193 | 5.45M | self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH) |
194 | 5.45M | } <thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip Line | Count | Source | 192 | 177k | fn skip(&mut self, field_type: TType) -> crate::Result<()> { | 193 | 177k | self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH) | 194 | 177k | } |
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::skip Unexecuted instantiation: <thrift::protocol::stored::TStoredInputProtocol as thrift::protocol::TInputProtocol>::skip Unexecuted instantiation: <thrift::protocol::compact::TCompactInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::skip <thrift::protocol::compact::TCompactInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip Line | Count | Source | 192 | 2.24M | fn skip(&mut self, field_type: TType) -> crate::Result<()> { | 193 | 2.24M | self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH) | 194 | 2.24M | } |
<thrift::protocol::compact::TCompactInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip Line | Count | Source | 192 | 2.97M | fn skip(&mut self, field_type: TType) -> crate::Result<()> { | 193 | 2.97M | self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH) | 194 | 2.97M | } |
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip Line | Count | Source | 192 | 63.0k | fn skip(&mut self, field_type: TType) -> crate::Result<()> { | 193 | 63.0k | self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH) | 194 | 63.0k | } |
|
195 | | /// Skip a field with type `field_type` recursively up to `depth` levels. |
196 | 6.40M | fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> { |
197 | 6.40M | if depth == 0 { |
198 | 7 | return Err(crate::Error::Protocol(ProtocolError { |
199 | 7 | kind: ProtocolErrorKind::DepthLimit, |
200 | 7 | message: format!("cannot parse past {:?}", field_type), |
201 | 7 | })); |
202 | 6.40M | } |
203 | | |
204 | 6.40M | match field_type { |
205 | 4.74M | TType::Bool => self.read_bool().map(|_| ()), |
206 | 274k | TType::I08 => self.read_i8().map(|_| ()), |
207 | 71.4k | TType::I16 => self.read_i16().map(|_| ()), |
208 | 134k | TType::I32 => self.read_i32().map(|_| ()), |
209 | 138k | TType::I64 => self.read_i64().map(|_| ()), |
210 | 23.8k | TType::Double => self.read_double().map(|_| ()), |
211 | 36.0k | TType::String => self.read_string().map(|_| ()), |
212 | 276k | TType::Uuid => self.read_uuid().map(|_| ()), |
213 | | TType::Struct => { |
214 | 44.6k | self.read_struct_begin()?; |
215 | | loop { |
216 | 739k | let field_ident = self.read_field_begin()?; |
217 | 738k | if field_ident.field_type == TType::Stop { |
218 | 42.3k | break; |
219 | 696k | } |
220 | 696k | self.skip_till_depth(field_ident.field_type, depth - 1)?; |
221 | | } |
222 | 42.3k | self.read_struct_end() |
223 | | } |
224 | | TType::List => { |
225 | 623k | let list_ident = self.read_list_begin()?; |
226 | 623k | for _ in 0..list_ident.size { |
227 | 211k | self.skip_till_depth(list_ident.element_type, depth - 1)?; |
228 | | } |
229 | 622k | self.read_list_end() |
230 | | } |
231 | | TType::Set => { |
232 | 27.5k | let set_ident = self.read_set_begin()?; |
233 | 27.2k | for _ in 0..set_ident.size { |
234 | 25.2k | self.skip_till_depth(set_ident.element_type, depth - 1)?; |
235 | | } |
236 | 25.8k | self.read_set_end() |
237 | | } |
238 | | TType::Map => { |
239 | 7.59k | let map_ident = self.read_map_begin()?; |
240 | 7.24k | for _ in 0..map_ident.size { |
241 | 9.45k | let key_type = map_ident |
242 | 9.45k | .key_type |
243 | 9.45k | .expect("non-zero sized map should contain key type"); |
244 | 9.45k | let val_type = map_ident |
245 | 9.45k | .value_type |
246 | 9.45k | .expect("non-zero sized map should contain value type"); |
247 | 9.45k | self.skip_till_depth(key_type, depth - 1)?; |
248 | 8.72k | self.skip_till_depth(val_type, depth - 1)?; |
249 | | } |
250 | 6.16k | self.read_map_end() |
251 | | } |
252 | 194 | u => Err(crate::Error::Protocol(ProtocolError { |
253 | 194 | kind: ProtocolErrorKind::Unknown, |
254 | 194 | message: format!("cannot skip field type {:?}", &u), |
255 | 194 | })), |
256 | | } |
257 | 6.40M | } <thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip_till_depth Line | Count | Source | 196 | 296k | fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> { | 197 | 296k | if depth == 0 { | 198 | 1 | return Err(crate::Error::Protocol(ProtocolError { | 199 | 1 | kind: ProtocolErrorKind::DepthLimit, | 200 | 1 | message: format!("cannot parse past {:?}", field_type), | 201 | 1 | })); | 202 | 296k | } | 203 | | | 204 | 296k | match field_type { | 205 | 71.0k | TType::Bool => self.read_bool().map(|_| ()), | 206 | 191k | TType::I08 => self.read_i8().map(|_| ()), | 207 | 637 | TType::I16 => self.read_i16().map(|_| ()), | 208 | 2.82k | TType::I32 => self.read_i32().map(|_| ()), | 209 | 1.68k | TType::I64 => self.read_i64().map(|_| ()), | 210 | 2.88k | TType::Double => self.read_double().map(|_| ()), | 211 | 4.99k | TType::String => self.read_string().map(|_| ()), | 212 | 1.98k | TType::Uuid => self.read_uuid().map(|_| ()), | 213 | | TType::Struct => { | 214 | 11.2k | self.read_struct_begin()?; | 215 | | loop { | 216 | 123k | let field_ident = self.read_field_begin()?; | 217 | 123k | if field_ident.field_type == TType::Stop { | 218 | 10.6k | break; | 219 | 112k | } | 220 | 112k | self.skip_till_depth(field_ident.field_type, depth - 1)?; | 221 | | } | 222 | 10.6k | self.read_struct_end() | 223 | | } | 224 | | TType::List => { | 225 | 2.16k | let list_ident = self.read_list_begin()?; | 226 | 2.09k | for _ in 0..list_ident.size { | 227 | 2.08k | self.skip_till_depth(list_ident.element_type, depth - 1)?; | 228 | | } | 229 | 1.96k | self.read_list_end() | 230 | | } | 231 | | TType::Set => { | 232 | 4.52k | let set_ident = self.read_set_begin()?; | 233 | 4.40k | for _ in 0..set_ident.size { | 234 | 3.72k | self.skip_till_depth(set_ident.element_type, depth - 1)?; | 235 | | } | 236 | 4.12k | self.read_set_end() | 237 | | } | 238 | | TType::Map => { | 239 | 972 | let map_ident = self.read_map_begin()?; | 240 | 907 | for _ in 0..map_ident.size { | 241 | 879 | let key_type = map_ident | 242 | 879 | .key_type | 243 | 879 | .expect("non-zero sized map should contain key type"); | 244 | 879 | let val_type = map_ident | 245 | 879 | .value_type | 246 | 879 | .expect("non-zero sized map should contain value type"); | 247 | 879 | self.skip_till_depth(key_type, depth - 1)?; | 248 | 766 | self.skip_till_depth(val_type, depth - 1)?; | 249 | | } | 250 | 722 | self.read_map_end() | 251 | | } | 252 | 71 | u => Err(crate::Error::Protocol(ProtocolError { | 253 | 71 | kind: ProtocolErrorKind::Unknown, | 254 | 71 | message: format!("cannot skip field type {:?}", &u), | 255 | 71 | })), | 256 | | } | 257 | 296k | } |
Unexecuted instantiation: <thrift::protocol::binary::TBinaryInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::skip_till_depth Unexecuted instantiation: <thrift::protocol::stored::TStoredInputProtocol as thrift::protocol::TInputProtocol>::skip_till_depth Unexecuted instantiation: <thrift::protocol::compact::TCompactInputProtocol<alloc::boxed::Box<dyn thrift::transport::TReadTransport + core::marker::Send>> as thrift::protocol::TInputProtocol>::skip_till_depth <thrift::protocol::compact::TCompactInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip_till_depth Line | Count | Source | 196 | 2.85M | fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> { | 197 | 2.85M | if depth == 0 { | 198 | 2 | return Err(crate::Error::Protocol(ProtocolError { | 199 | 2 | kind: ProtocolErrorKind::DepthLimit, | 200 | 2 | message: format!("cannot parse past {:?}", field_type), | 201 | 2 | })); | 202 | 2.85M | } | 203 | | | 204 | 2.85M | match field_type { | 205 | 1.90M | TType::Bool => self.read_bool().map(|_| ()), | 206 | 16.0k | TType::I08 => self.read_i8().map(|_| ()), | 207 | 54.6k | TType::I16 => self.read_i16().map(|_| ()), | 208 | 110k | TType::I32 => self.read_i32().map(|_| ()), | 209 | 114k | TType::I64 => self.read_i64().map(|_| ()), | 210 | 7.89k | TType::Double => self.read_double().map(|_| ()), | 211 | 12.5k | TType::String => self.read_string().map(|_| ()), | 212 | 1.89k | TType::Uuid => self.read_uuid().map(|_| ()), | 213 | | TType::Struct => { | 214 | 13.8k | self.read_struct_begin()?; | 215 | | loop { | 216 | 434k | let field_ident = self.read_field_begin()?; | 217 | 434k | if field_ident.field_type == TType::Stop { | 218 | 13.2k | break; | 219 | 421k | } | 220 | 421k | self.skip_till_depth(field_ident.field_type, depth - 1)?; | 221 | | } | 222 | 13.2k | self.read_struct_end() | 223 | | } | 224 | | TType::List => { | 225 | 602k | let list_ident = self.read_list_begin()?; | 226 | 602k | for _ in 0..list_ident.size { | 227 | 179k | self.skip_till_depth(list_ident.element_type, depth - 1)?; | 228 | | } | 229 | 601k | self.read_list_end() | 230 | | } | 231 | | TType::Set => { | 232 | 4.16k | let set_ident = self.read_set_begin()?; | 233 | 4.11k | for _ in 0..set_ident.size { | 234 | 5.77k | self.skip_till_depth(set_ident.element_type, depth - 1)?; | 235 | | } | 236 | 3.74k | self.read_set_end() | 237 | | } | 238 | | TType::Map => { | 239 | 3.82k | let map_ident = self.read_map_begin()?; | 240 | 3.69k | for _ in 0..map_ident.size { | 241 | 2.83k | let key_type = map_ident | 242 | 2.83k | .key_type | 243 | 2.83k | .expect("non-zero sized map should contain key type"); | 244 | 2.83k | let val_type = map_ident | 245 | 2.83k | .value_type | 246 | 2.83k | .expect("non-zero sized map should contain value type"); | 247 | 2.83k | self.skip_till_depth(key_type, depth - 1)?; | 248 | 2.64k | self.skip_till_depth(val_type, depth - 1)?; | 249 | | } | 250 | 3.39k | self.read_map_end() | 251 | | } | 252 | 24 | u => Err(crate::Error::Protocol(ProtocolError { | 253 | 24 | kind: ProtocolErrorKind::Unknown, | 254 | 24 | message: format!("cannot skip field type {:?}", &u), | 255 | 24 | })), | 256 | | } | 257 | 2.85M | } |
<thrift::protocol::compact::TCompactInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip_till_depth Line | Count | Source | 196 | 3.17M | fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> { | 197 | 3.17M | if depth == 0 { | 198 | 2 | return Err(crate::Error::Protocol(ProtocolError { | 199 | 2 | kind: ProtocolErrorKind::DepthLimit, | 200 | 2 | message: format!("cannot parse past {:?}", field_type), | 201 | 2 | })); | 202 | 3.17M | } | 203 | | | 204 | 3.17M | match field_type { | 205 | 2.75M | TType::Bool => self.read_bool().map(|_| ()), | 206 | 28.7k | TType::I08 => self.read_i8().map(|_| ()), | 207 | 13.8k | TType::I16 => self.read_i16().map(|_| ()), | 208 | 17.1k | TType::I32 => self.read_i32().map(|_| ()), | 209 | 19.1k | TType::I64 => self.read_i64().map(|_| ()), | 210 | 8.63k | TType::Double => self.read_double().map(|_| ()), | 211 | 13.1k | TType::String => self.read_string().map(|_| ()), | 212 | 270k | TType::Uuid => self.read_uuid().map(|_| ()), | 213 | | TType::Struct => { | 214 | 10.1k | self.read_struct_begin()?; | 215 | | loop { | 216 | 164k | let field_ident = self.read_field_begin()?; | 217 | 164k | if field_ident.field_type == TType::Stop { | 218 | 9.50k | break; | 219 | 154k | } | 220 | 154k | self.skip_till_depth(field_ident.field_type, depth - 1)?; | 221 | | } | 222 | 9.50k | self.read_struct_end() | 223 | | } | 224 | | TType::List => { | 225 | 18.0k | let list_ident = self.read_list_begin()?; | 226 | 18.0k | for _ in 0..list_ident.size { | 227 | 26.0k | self.skip_till_depth(list_ident.element_type, depth - 1)?; | 228 | | } | 229 | 17.5k | self.read_list_end() | 230 | | } | 231 | | TType::Set => { | 232 | 17.5k | let set_ident = self.read_set_begin()?; | 233 | 17.4k | for _ in 0..set_ident.size { | 234 | 11.9k | self.skip_till_depth(set_ident.element_type, depth - 1)?; | 235 | | } | 236 | 16.9k | self.read_set_end() | 237 | | } | 238 | | TType::Map => { | 239 | 1.25k | let map_ident = self.read_map_begin()?; | 240 | 1.16k | for _ in 0..map_ident.size { | 241 | 4.71k | let key_type = map_ident | 242 | 4.71k | .key_type | 243 | 4.71k | .expect("non-zero sized map should contain key type"); | 244 | 4.71k | let val_type = map_ident | 245 | 4.71k | .value_type | 246 | 4.71k | .expect("non-zero sized map should contain value type"); | 247 | 4.71k | self.skip_till_depth(key_type, depth - 1)?; | 248 | 4.61k | self.skip_till_depth(val_type, depth - 1)?; | 249 | | } | 250 | 978 | self.read_map_end() | 251 | | } | 252 | 22 | u => Err(crate::Error::Protocol(ProtocolError { | 253 | 22 | kind: ProtocolErrorKind::Unknown, | 254 | 22 | message: format!("cannot skip field type {:?}", &u), | 255 | 22 | })), | 256 | | } | 257 | 3.17M | } |
<thrift::protocol::binary::TBinaryInputProtocol<thrift::transport::mem::TBufferChannel> as thrift::protocol::TInputProtocol>::skip_till_depth Line | Count | Source | 196 | 80.1k | fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> { | 197 | 80.1k | if depth == 0 { | 198 | 2 | return Err(crate::Error::Protocol(ProtocolError { | 199 | 2 | kind: ProtocolErrorKind::DepthLimit, | 200 | 2 | message: format!("cannot parse past {:?}", field_type), | 201 | 2 | })); | 202 | 80.1k | } | 203 | | | 204 | 80.1k | match field_type { | 205 | 8.28k | TType::Bool => self.read_bool().map(|_| ()), | 206 | 37.9k | TType::I08 => self.read_i8().map(|_| ()), | 207 | 2.31k | TType::I16 => self.read_i16().map(|_| ()), | 208 | 3.60k | TType::I32 => self.read_i32().map(|_| ()), | 209 | 2.93k | TType::I64 => self.read_i64().map(|_| ()), | 210 | 4.44k | TType::Double => self.read_double().map(|_| ()), | 211 | 5.33k | TType::String => self.read_string().map(|_| ()), | 212 | 1.91k | TType::Uuid => self.read_uuid().map(|_| ()), | 213 | | TType::Struct => { | 214 | 9.27k | self.read_struct_begin()?; | 215 | | loop { | 216 | 16.6k | let field_ident = self.read_field_begin()?; | 217 | 16.5k | if field_ident.field_type == TType::Stop { | 218 | 8.88k | break; | 219 | 7.66k | } | 220 | 7.66k | self.skip_till_depth(field_ident.field_type, depth - 1)?; | 221 | | } | 222 | 8.88k | self.read_struct_end() | 223 | | } | 224 | | TType::List => { | 225 | 1.15k | let list_ident = self.read_list_begin()?; | 226 | 1.07k | for _ in 0..list_ident.size { | 227 | 3.95k | self.skip_till_depth(list_ident.element_type, depth - 1)?; | 228 | | } | 229 | 950 | self.read_list_end() | 230 | | } | 231 | | TType::Set => { | 232 | 1.29k | let set_ident = self.read_set_begin()?; | 233 | 1.19k | for _ in 0..set_ident.size { | 234 | 3.78k | self.skip_till_depth(set_ident.element_type, depth - 1)?; | 235 | | } | 236 | 1.03k | self.read_set_end() | 237 | | } | 238 | | TType::Map => { | 239 | 1.53k | let map_ident = self.read_map_begin()?; | 240 | 1.48k | for _ in 0..map_ident.size { | 241 | 1.03k | let key_type = map_ident | 242 | 1.03k | .key_type | 243 | 1.03k | .expect("non-zero sized map should contain key type"); | 244 | 1.03k | let val_type = map_ident | 245 | 1.03k | .value_type | 246 | 1.03k | .expect("non-zero sized map should contain value type"); | 247 | 1.03k | self.skip_till_depth(key_type, depth - 1)?; | 248 | 699 | self.skip_till_depth(val_type, depth - 1)?; | 249 | | } | 250 | 1.07k | self.read_map_end() | 251 | | } | 252 | 77 | u => Err(crate::Error::Protocol(ProtocolError { | 253 | 77 | kind: ProtocolErrorKind::Unknown, | 254 | 77 | message: format!("cannot skip field type {:?}", &u), | 255 | 77 | })), | 256 | | } | 257 | 80.1k | } |
|
258 | | |
259 | | // utility (DO NOT USE IN GENERATED CODE!!!!) |
260 | | // |
261 | | |
262 | | /// Read an unsigned byte. |
263 | | /// |
264 | | /// This method should **never** be used in generated code. |
265 | | fn read_byte(&mut self) -> crate::Result<u8>; |
266 | | |
267 | | /// Get the minimum number of bytes a type will consume on the wire. |
268 | | /// This picks the minimum possible across all protocols (so currently matches the compact protocol). |
269 | | /// |
270 | | /// This is used for pre-allocation size checks. |
271 | | /// The actual data may be larger (e.g., for strings, lists, etc.). |
272 | 0 | fn min_serialized_size(&self, field_type: TType) -> usize { |
273 | 0 | self::compact::compact_protocol_min_serialized_size(field_type) |
274 | 0 | } |
275 | | } |
276 | | |
277 | | /// Converts Thrift identifiers, primitives, containers or structs into a |
278 | | /// stream of bytes. |
279 | | /// |
280 | | /// This trait does not deal with higher-level Thrift concepts like structs or |
281 | | /// exceptions - only with primitives and message or container boundaries. |
282 | | /// Write methods take an identifier (for example, `TMessageIdentifier`) or a |
283 | | /// primitive. Any or all of the fields in an identifier may be omitted when |
284 | | /// writing to the transport. Write methods may even be noops. All of this is |
285 | | /// transparent to the caller; as long as a matching `TInputProtocol` |
286 | | /// implementation is used, received messages will be decoded correctly. |
287 | | /// |
288 | | /// All methods return a `thrift::Result`. If an `Err` is returned the protocol |
289 | | /// instance and its underlying transport should be terminated. |
290 | | /// |
291 | | /// # Examples |
292 | | /// |
293 | | /// Create and use a `TOutputProtocol` |
294 | | /// |
295 | | /// ```no_run |
296 | | /// use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType}; |
297 | | /// use thrift::transport::TTcpChannel; |
298 | | /// |
299 | | /// let mut channel = TTcpChannel::new(); |
300 | | /// channel.open("127.0.0.1:9090").unwrap(); |
301 | | /// |
302 | | /// let mut protocol = TBinaryOutputProtocol::new(channel, true); |
303 | | /// |
304 | | /// protocol.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap(); |
305 | | /// protocol.write_string("foo").unwrap(); |
306 | | /// protocol.write_field_end().unwrap(); |
307 | | /// ``` |
308 | | pub trait TOutputProtocol { |
309 | | /// Write the beginning of a Thrift message. |
310 | | fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()>; |
311 | | /// Write the end of a Thrift message. |
312 | | fn write_message_end(&mut self) -> crate::Result<()>; |
313 | | /// Write the beginning of a Thrift struct. |
314 | | fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()>; |
315 | | /// Write the end of a Thrift struct. |
316 | | fn write_struct_end(&mut self) -> crate::Result<()>; |
317 | | /// Write the beginning of a Thrift field. |
318 | | fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()>; |
319 | | /// Write the end of a Thrift field. |
320 | | fn write_field_end(&mut self) -> crate::Result<()>; |
321 | | /// Write a STOP field indicating that all the fields in a struct have been |
322 | | /// written. |
323 | | fn write_field_stop(&mut self) -> crate::Result<()>; |
324 | | /// Write a bool. |
325 | | fn write_bool(&mut self, b: bool) -> crate::Result<()>; |
326 | | /// Write a fixed-length byte array. |
327 | | fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()>; |
328 | | /// Write an 8-bit signed integer. |
329 | | fn write_i8(&mut self, i: i8) -> crate::Result<()>; |
330 | | /// Write a 16-bit signed integer. |
331 | | fn write_i16(&mut self, i: i16) -> crate::Result<()>; |
332 | | /// Write a 32-bit signed integer. |
333 | | fn write_i32(&mut self, i: i32) -> crate::Result<()>; |
334 | | /// Write a 64-bit signed integer. |
335 | | fn write_i64(&mut self, i: i64) -> crate::Result<()>; |
336 | | /// Write a 64-bit float. |
337 | | fn write_double(&mut self, d: f64) -> crate::Result<()>; |
338 | | /// Write a UUID |
339 | | fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()>; |
340 | | /// Write a fixed-length string. |
341 | | fn write_string(&mut self, s: &str) -> crate::Result<()>; |
342 | | /// Write the beginning of a list. |
343 | | fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()>; |
344 | | /// Write the end of a list. |
345 | | fn write_list_end(&mut self) -> crate::Result<()>; |
346 | | /// Write the beginning of a set. |
347 | | fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()>; |
348 | | /// Write the end of a set. |
349 | | fn write_set_end(&mut self) -> crate::Result<()>; |
350 | | /// Write the beginning of a map. |
351 | | fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()>; |
352 | | /// Write the end of a map. |
353 | | fn write_map_end(&mut self) -> crate::Result<()>; |
354 | | /// Flush buffered bytes to the underlying transport. |
355 | | fn flush(&mut self) -> crate::Result<()>; |
356 | | |
357 | | // utility (DO NOT USE IN GENERATED CODE!!!!) |
358 | | // |
359 | | |
360 | | /// Write an unsigned byte. |
361 | | /// |
362 | | /// This method should **never** be used in generated code. |
363 | | fn write_byte(&mut self, b: u8) -> crate::Result<()>; // FIXME: REMOVE |
364 | | } |
365 | | |
366 | | impl<P> TInputProtocol for Box<P> |
367 | | where |
368 | | P: TInputProtocol + ?Sized, |
369 | | { |
370 | | fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> { |
371 | | (**self).read_message_begin() |
372 | | } |
373 | | |
374 | | fn read_message_end(&mut self) -> crate::Result<()> { |
375 | | (**self).read_message_end() |
376 | | } |
377 | | |
378 | | fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> { |
379 | | (**self).read_struct_begin() |
380 | | } |
381 | | |
382 | | fn read_struct_end(&mut self) -> crate::Result<()> { |
383 | | (**self).read_struct_end() |
384 | | } |
385 | | |
386 | | fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> { |
387 | | (**self).read_field_begin() |
388 | | } |
389 | | |
390 | | fn read_field_end(&mut self) -> crate::Result<()> { |
391 | | (**self).read_field_end() |
392 | | } |
393 | | |
394 | | fn read_bool(&mut self) -> crate::Result<bool> { |
395 | | (**self).read_bool() |
396 | | } |
397 | | |
398 | | fn read_bytes(&mut self) -> crate::Result<Vec<u8>> { |
399 | | (**self).read_bytes() |
400 | | } |
401 | | |
402 | | fn read_i8(&mut self) -> crate::Result<i8> { |
403 | | (**self).read_i8() |
404 | | } |
405 | | |
406 | | fn read_i16(&mut self) -> crate::Result<i16> { |
407 | | (**self).read_i16() |
408 | | } |
409 | | |
410 | | fn read_i32(&mut self) -> crate::Result<i32> { |
411 | | (**self).read_i32() |
412 | | } |
413 | | |
414 | | fn read_i64(&mut self) -> crate::Result<i64> { |
415 | | (**self).read_i64() |
416 | | } |
417 | | |
418 | | fn read_double(&mut self) -> crate::Result<f64> { |
419 | | (**self).read_double() |
420 | | } |
421 | | |
422 | | fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> { |
423 | | (**self).read_uuid() |
424 | | } |
425 | | |
426 | | fn read_string(&mut self) -> crate::Result<String> { |
427 | | (**self).read_string() |
428 | | } |
429 | | |
430 | | fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> { |
431 | | (**self).read_list_begin() |
432 | | } |
433 | | |
434 | | fn read_list_end(&mut self) -> crate::Result<()> { |
435 | | (**self).read_list_end() |
436 | | } |
437 | | |
438 | | fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> { |
439 | | (**self).read_set_begin() |
440 | | } |
441 | | |
442 | | fn read_set_end(&mut self) -> crate::Result<()> { |
443 | | (**self).read_set_end() |
444 | | } |
445 | | |
446 | | fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> { |
447 | | (**self).read_map_begin() |
448 | | } |
449 | | |
450 | | fn read_map_end(&mut self) -> crate::Result<()> { |
451 | | (**self).read_map_end() |
452 | | } |
453 | | |
454 | | fn read_byte(&mut self) -> crate::Result<u8> { |
455 | | (**self).read_byte() |
456 | | } |
457 | | |
458 | | fn min_serialized_size(&self, field_type: TType) -> usize { |
459 | | (**self).min_serialized_size(field_type) |
460 | | } |
461 | | } |
462 | | |
463 | | impl<P> TOutputProtocol for Box<P> |
464 | | where |
465 | | P: TOutputProtocol + ?Sized, |
466 | | { |
467 | | fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> { |
468 | | (**self).write_message_begin(identifier) |
469 | | } |
470 | | |
471 | | fn write_message_end(&mut self) -> crate::Result<()> { |
472 | | (**self).write_message_end() |
473 | | } |
474 | | |
475 | | fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()> { |
476 | | (**self).write_struct_begin(identifier) |
477 | | } |
478 | | |
479 | | fn write_struct_end(&mut self) -> crate::Result<()> { |
480 | | (**self).write_struct_end() |
481 | | } |
482 | | |
483 | | fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> { |
484 | | (**self).write_field_begin(identifier) |
485 | | } |
486 | | |
487 | | fn write_field_end(&mut self) -> crate::Result<()> { |
488 | | (**self).write_field_end() |
489 | | } |
490 | | |
491 | | fn write_field_stop(&mut self) -> crate::Result<()> { |
492 | | (**self).write_field_stop() |
493 | | } |
494 | | |
495 | | fn write_bool(&mut self, b: bool) -> crate::Result<()> { |
496 | | (**self).write_bool(b) |
497 | | } |
498 | | |
499 | | fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> { |
500 | | (**self).write_bytes(b) |
501 | | } |
502 | | |
503 | | fn write_i8(&mut self, i: i8) -> crate::Result<()> { |
504 | | (**self).write_i8(i) |
505 | | } |
506 | | |
507 | | fn write_i16(&mut self, i: i16) -> crate::Result<()> { |
508 | | (**self).write_i16(i) |
509 | | } |
510 | | |
511 | | fn write_i32(&mut self, i: i32) -> crate::Result<()> { |
512 | | (**self).write_i32(i) |
513 | | } |
514 | | |
515 | | fn write_i64(&mut self, i: i64) -> crate::Result<()> { |
516 | | (**self).write_i64(i) |
517 | | } |
518 | | |
519 | | fn write_double(&mut self, d: f64) -> crate::Result<()> { |
520 | | (**self).write_double(d) |
521 | | } |
522 | | |
523 | | fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> { |
524 | | (**self).write_uuid(uuid) |
525 | | } |
526 | | |
527 | | fn write_string(&mut self, s: &str) -> crate::Result<()> { |
528 | | (**self).write_string(s) |
529 | | } |
530 | | |
531 | | fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> { |
532 | | (**self).write_list_begin(identifier) |
533 | | } |
534 | | |
535 | | fn write_list_end(&mut self) -> crate::Result<()> { |
536 | | (**self).write_list_end() |
537 | | } |
538 | | |
539 | | fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> { |
540 | | (**self).write_set_begin(identifier) |
541 | | } |
542 | | |
543 | | fn write_set_end(&mut self) -> crate::Result<()> { |
544 | | (**self).write_set_end() |
545 | | } |
546 | | |
547 | | fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> { |
548 | | (**self).write_map_begin(identifier) |
549 | | } |
550 | | |
551 | | fn write_map_end(&mut self) -> crate::Result<()> { |
552 | | (**self).write_map_end() |
553 | | } |
554 | | |
555 | | fn flush(&mut self) -> crate::Result<()> { |
556 | | (**self).flush() |
557 | | } |
558 | | |
559 | | fn write_byte(&mut self, b: u8) -> crate::Result<()> { |
560 | | (**self).write_byte(b) |
561 | | } |
562 | | } |
563 | | |
564 | | /// Helper type used by servers to create `TInputProtocol` instances for |
565 | | /// accepted client connections. |
566 | | /// |
567 | | /// # Examples |
568 | | /// |
569 | | /// Create a `TInputProtocolFactory` and use it to create a `TInputProtocol`. |
570 | | /// |
571 | | /// ```no_run |
572 | | /// use thrift::protocol::{TBinaryInputProtocolFactory, TInputProtocolFactory}; |
573 | | /// use thrift::transport::TTcpChannel; |
574 | | /// |
575 | | /// let mut channel = TTcpChannel::new(); |
576 | | /// channel.open("127.0.0.1:9090").unwrap(); |
577 | | /// |
578 | | /// let factory = TBinaryInputProtocolFactory::new(); |
579 | | /// let protocol = factory.create(Box::new(channel)); |
580 | | /// ``` |
581 | | pub trait TInputProtocolFactory { |
582 | | /// Create a `TInputProtocol` that reads bytes from `transport`. |
583 | | fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send>; |
584 | | } |
585 | | |
586 | | impl<T> TInputProtocolFactory for Box<T> |
587 | | where |
588 | | T: TInputProtocolFactory + ?Sized, |
589 | | { |
590 | | fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send> { |
591 | | (**self).create(transport) |
592 | | } |
593 | | } |
594 | | |
595 | | /// Helper type used by servers to create `TOutputProtocol` instances for |
596 | | /// accepted client connections. |
597 | | /// |
598 | | /// # Examples |
599 | | /// |
600 | | /// Create a `TOutputProtocolFactory` and use it to create a `TOutputProtocol`. |
601 | | /// |
602 | | /// ```no_run |
603 | | /// use thrift::protocol::{TBinaryOutputProtocolFactory, TOutputProtocolFactory}; |
604 | | /// use thrift::transport::TTcpChannel; |
605 | | /// |
606 | | /// let mut channel = TTcpChannel::new(); |
607 | | /// channel.open("127.0.0.1:9090").unwrap(); |
608 | | /// |
609 | | /// let factory = TBinaryOutputProtocolFactory::new(); |
610 | | /// let protocol = factory.create(Box::new(channel)); |
611 | | /// ``` |
612 | | pub trait TOutputProtocolFactory { |
613 | | /// Create a `TOutputProtocol` that writes bytes to `transport`. |
614 | | fn create(&self, transport: Box<dyn TWriteTransport + Send>) |
615 | | -> Box<dyn TOutputProtocol + Send>; |
616 | | } |
617 | | |
618 | | impl<T> TOutputProtocolFactory for Box<T> |
619 | | where |
620 | | T: TOutputProtocolFactory + ?Sized, |
621 | | { |
622 | | fn create( |
623 | | &self, |
624 | | transport: Box<dyn TWriteTransport + Send>, |
625 | | ) -> Box<dyn TOutputProtocol + Send> { |
626 | | (**self).create(transport) |
627 | | } |
628 | | } |
629 | | |
630 | | /// Thrift message identifier. |
631 | | #[derive(Clone, Debug, Eq, PartialEq)] |
632 | | pub struct TMessageIdentifier { |
633 | | /// Service call the message is associated with. |
634 | | pub name: String, |
635 | | /// Message type. |
636 | | pub message_type: TMessageType, |
637 | | /// Ordered sequence number identifying the message. |
638 | | pub sequence_number: i32, |
639 | | } |
640 | | |
641 | | impl TMessageIdentifier { |
642 | | /// Create a `TMessageIdentifier` for a Thrift service-call named `name` |
643 | | /// with message type `message_type` and sequence number `sequence_number`. |
644 | 0 | pub fn new<S: Into<String>>( |
645 | 0 | name: S, |
646 | 0 | message_type: TMessageType, |
647 | 0 | sequence_number: i32, |
648 | 0 | ) -> TMessageIdentifier { |
649 | 0 | TMessageIdentifier { |
650 | 0 | name: name.into(), |
651 | 0 | message_type, |
652 | 0 | sequence_number, |
653 | 0 | } |
654 | 0 | } Unexecuted instantiation: <thrift::protocol::TMessageIdentifier>::new::<alloc::string::String> Unexecuted instantiation: <thrift::protocol::TMessageIdentifier>::new::<&str> |
655 | | } |
656 | | |
657 | | /// Thrift struct identifier. |
658 | | #[derive(Clone, Debug, Eq, PartialEq)] |
659 | | pub struct TStructIdentifier { |
660 | | /// Name of the encoded Thrift struct. |
661 | | pub name: String, |
662 | | } |
663 | | |
664 | | impl TStructIdentifier { |
665 | | /// Create a `TStructIdentifier` for a struct named `name`. |
666 | 492k | pub fn new<S: Into<String>>(name: S) -> TStructIdentifier { |
667 | 492k | TStructIdentifier { name: name.into() } |
668 | 492k | } |
669 | | } |
670 | | |
671 | | /// Thrift field identifier. |
672 | | #[derive(Clone, Debug, Eq, PartialEq)] |
673 | | pub struct TFieldIdentifier { |
674 | | /// Name of the Thrift field. |
675 | | /// |
676 | | /// `None` if it's not sent over the wire. |
677 | | pub name: Option<String>, |
678 | | /// Field type. |
679 | | /// |
680 | | /// This may be a primitive, container, or a struct. |
681 | | pub field_type: TType, |
682 | | /// Thrift field id. |
683 | | /// |
684 | | /// `None` only if `field_type` is `TType::Stop`. |
685 | | pub id: Option<i16>, |
686 | | } |
687 | | |
688 | | impl TFieldIdentifier { |
689 | | /// Create a `TFieldIdentifier` for a field named `name` with type |
690 | | /// `field_type` and field id `id`. |
691 | | /// |
692 | | /// `id` should be `None` if `field_type` is `TType::Stop`. |
693 | 3.13M | pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier |
694 | 3.13M | where |
695 | 3.13M | N: Into<Option<S>>, |
696 | 3.13M | S: Into<String>, |
697 | 3.13M | I: Into<Option<i16>>, |
698 | | { |
699 | | TFieldIdentifier { |
700 | 3.13M | name: name.into().map(|n| n.into()), Unexecuted instantiation: <thrift::protocol::TFieldIdentifier>::new::<core::option::Option<alloc::string::String>, alloc::string::String, core::option::Option<i16>>::{closure#0}Unexecuted instantiation: <thrift::protocol::TFieldIdentifier>::new::<core::option::Option<alloc::string::String>, alloc::string::String, i16>::{closure#0}<thrift::protocol::TFieldIdentifier>::new::<&str, &str, i16>::{closure#0}Line | Count | Source | 700 | 830k | name: name.into().map(|n| n.into()), |
|
701 | 3.13M | field_type, |
702 | 3.13M | id: id.into(), |
703 | | } |
704 | 3.13M | } <thrift::protocol::TFieldIdentifier>::new::<core::option::Option<alloc::string::String>, alloc::string::String, core::option::Option<i16>> Line | Count | Source | 693 | 945k | pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier | 694 | 945k | where | 695 | 945k | N: Into<Option<S>>, | 696 | 945k | S: Into<String>, | 697 | 945k | I: Into<Option<i16>>, | 698 | | { | 699 | | TFieldIdentifier { | 700 | 945k | name: name.into().map(|n| n.into()), | 701 | 945k | field_type, | 702 | 945k | id: id.into(), | 703 | | } | 704 | 945k | } |
<thrift::protocol::TFieldIdentifier>::new::<core::option::Option<alloc::string::String>, alloc::string::String, i16> Line | Count | Source | 693 | 1.36M | pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier | 694 | 1.36M | where | 695 | 1.36M | N: Into<Option<S>>, | 696 | 1.36M | S: Into<String>, | 697 | 1.36M | I: Into<Option<i16>>, | 698 | | { | 699 | | TFieldIdentifier { | 700 | 1.36M | name: name.into().map(|n| n.into()), | 701 | 1.36M | field_type, | 702 | 1.36M | id: id.into(), | 703 | | } | 704 | 1.36M | } |
<thrift::protocol::TFieldIdentifier>::new::<&str, &str, i16> Line | Count | Source | 693 | 830k | pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier | 694 | 830k | where | 695 | 830k | N: Into<Option<S>>, | 696 | 830k | S: Into<String>, | 697 | 830k | I: Into<Option<i16>>, | 698 | | { | 699 | | TFieldIdentifier { | 700 | 830k | name: name.into().map(|n| n.into()), | 701 | 830k | field_type, | 702 | 830k | id: id.into(), | 703 | | } | 704 | 830k | } |
|
705 | | } |
706 | | |
707 | | /// Thrift list identifier. |
708 | | #[derive(Clone, Debug, Eq, PartialEq)] |
709 | | pub struct TListIdentifier { |
710 | | /// Type of the elements in the list. |
711 | | pub element_type: TType, |
712 | | /// Number of elements in the list. |
713 | | pub size: i32, |
714 | | } |
715 | | |
716 | | impl TListIdentifier { |
717 | | /// Create a `TListIdentifier` for a list with `size` elements of type |
718 | | /// `element_type`. |
719 | 3.09M | pub fn new(element_type: TType, size: i32) -> TListIdentifier { |
720 | 3.09M | TListIdentifier { element_type, size } |
721 | 3.09M | } |
722 | | } |
723 | | |
724 | | /// Thrift set identifier. |
725 | | #[derive(Clone, Debug, Eq, PartialEq)] |
726 | | pub struct TSetIdentifier { |
727 | | /// Type of the elements in the set. |
728 | | pub element_type: TType, |
729 | | /// Number of elements in the set. |
730 | | pub size: i32, |
731 | | } |
732 | | |
733 | | impl TSetIdentifier { |
734 | | /// Create a `TSetIdentifier` for a set with `size` elements of type |
735 | | /// `element_type`. |
736 | 243k | pub fn new(element_type: TType, size: i32) -> TSetIdentifier { |
737 | 243k | TSetIdentifier { element_type, size } |
738 | 243k | } |
739 | | } |
740 | | |
741 | | /// Thrift map identifier. |
742 | | #[derive(Clone, Debug, Eq, PartialEq)] |
743 | | pub struct TMapIdentifier { |
744 | | /// Map key type. |
745 | | pub key_type: Option<TType>, |
746 | | /// Map value type. |
747 | | pub value_type: Option<TType>, |
748 | | /// Number of entries in the map. |
749 | | pub size: i32, |
750 | | } |
751 | | |
752 | | impl TMapIdentifier { |
753 | | /// Create a `TMapIdentifier` for a map with `size` entries of type |
754 | | /// `key_type -> value_type`. |
755 | 204k | pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier |
756 | 204k | where |
757 | 204k | K: Into<Option<TType>>, |
758 | 204k | V: Into<Option<TType>>, |
759 | | { |
760 | 204k | TMapIdentifier { |
761 | 204k | key_type: key_type.into(), |
762 | 204k | value_type: value_type.into(), |
763 | 204k | size, |
764 | 204k | } |
765 | 204k | } <thrift::protocol::TMapIdentifier>::new::<core::option::Option<thrift::protocol::TType>, core::option::Option<thrift::protocol::TType>> Line | Count | Source | 755 | 12.1k | pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier | 756 | 12.1k | where | 757 | 12.1k | K: Into<Option<TType>>, | 758 | 12.1k | V: Into<Option<TType>>, | 759 | | { | 760 | 12.1k | TMapIdentifier { | 761 | 12.1k | key_type: key_type.into(), | 762 | 12.1k | value_type: value_type.into(), | 763 | 12.1k | size, | 764 | 12.1k | } | 765 | 12.1k | } |
<thrift::protocol::TMapIdentifier>::new::<thrift::protocol::TType, thrift::protocol::TType> Line | Count | Source | 755 | 192k | pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier | 756 | 192k | where | 757 | 192k | K: Into<Option<TType>>, | 758 | 192k | V: Into<Option<TType>>, | 759 | | { | 760 | 192k | TMapIdentifier { | 761 | 192k | key_type: key_type.into(), | 762 | 192k | value_type: value_type.into(), | 763 | 192k | size, | 764 | 192k | } | 765 | 192k | } |
|
766 | | } |
767 | | |
768 | | /// Thrift message types. |
769 | | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
770 | | pub enum TMessageType { |
771 | | /// Service-call request. |
772 | | Call, |
773 | | /// Service-call response. |
774 | | Reply, |
775 | | /// Unexpected error in the remote service. |
776 | | Exception, |
777 | | /// One-way service-call request (no response is expected). |
778 | | OneWay, |
779 | | } |
780 | | |
781 | | impl Display for TMessageType { |
782 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
783 | 0 | match *self { |
784 | 0 | TMessageType::Call => write!(f, "Call"), |
785 | 0 | TMessageType::Reply => write!(f, "Reply"), |
786 | 0 | TMessageType::Exception => write!(f, "Exception"), |
787 | 0 | TMessageType::OneWay => write!(f, "OneWay"), |
788 | | } |
789 | 0 | } |
790 | | } |
791 | | |
792 | | impl From<TMessageType> for u8 { |
793 | 0 | fn from(message_type: TMessageType) -> Self { |
794 | 0 | match message_type { |
795 | 0 | TMessageType::Call => 0x01, |
796 | 0 | TMessageType::Reply => 0x02, |
797 | 0 | TMessageType::Exception => 0x03, |
798 | 0 | TMessageType::OneWay => 0x04, |
799 | | } |
800 | 0 | } |
801 | | } |
802 | | |
803 | | impl TryFrom<u8> for TMessageType { |
804 | | type Error = crate::Error; |
805 | 0 | fn try_from(b: u8) -> Result<Self, Self::Error> { |
806 | 0 | match b { |
807 | 0 | 0x01 => Ok(TMessageType::Call), |
808 | 0 | 0x02 => Ok(TMessageType::Reply), |
809 | 0 | 0x03 => Ok(TMessageType::Exception), |
810 | 0 | 0x04 => Ok(TMessageType::OneWay), |
811 | 0 | unkn => Err(crate::Error::Protocol(ProtocolError { |
812 | 0 | kind: ProtocolErrorKind::InvalidData, |
813 | 0 | message: format!("cannot convert {} to TMessageType", unkn), |
814 | 0 | })), |
815 | | } |
816 | 0 | } |
817 | | } |
818 | | |
819 | | /// Thrift struct-field types. |
820 | | #[derive(Clone, Copy, Debug, Eq, PartialEq)] |
821 | | pub enum TType { |
822 | | /// Indicates that there are no more serialized fields in this Thrift struct. |
823 | | Stop, |
824 | | /// Void (`()`) field. |
825 | | Void, |
826 | | /// Boolean. |
827 | | Bool, |
828 | | /// Signed 8-bit int. |
829 | | I08, |
830 | | /// Double-precision number. |
831 | | Double, |
832 | | /// Signed 16-bit int. |
833 | | I16, |
834 | | /// Signed 32-bit int. |
835 | | I32, |
836 | | /// Signed 64-bit int. |
837 | | I64, |
838 | | /// UTF-8 string. |
839 | | String, |
840 | | /// UTF-7 string. *Unsupported*. |
841 | | Utf7, |
842 | | /// Thrift struct. |
843 | | Struct, |
844 | | /// Map. |
845 | | Map, |
846 | | /// Set. |
847 | | Set, |
848 | | /// List. |
849 | | List, |
850 | | /// Uuid. |
851 | | Uuid, |
852 | | } |
853 | | |
854 | | impl Display for TType { |
855 | 0 | fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
856 | 0 | match *self { |
857 | 0 | TType::Stop => write!(f, "STOP"), |
858 | 0 | TType::Void => write!(f, "void"), |
859 | 0 | TType::Bool => write!(f, "bool"), |
860 | 0 | TType::I08 => write!(f, "i08"), |
861 | 0 | TType::Double => write!(f, "double"), |
862 | 0 | TType::I16 => write!(f, "i16"), |
863 | 0 | TType::I32 => write!(f, "i32"), |
864 | 0 | TType::I64 => write!(f, "i64"), |
865 | 0 | TType::String => write!(f, "string"), |
866 | 0 | TType::Utf7 => write!(f, "UTF7"), |
867 | 0 | TType::Struct => write!(f, "struct"), |
868 | 0 | TType::Map => write!(f, "map"), |
869 | 0 | TType::Set => write!(f, "set"), |
870 | 0 | TType::List => write!(f, "list"), |
871 | 0 | TType::Uuid => write!(f, "UUID"), |
872 | | } |
873 | 0 | } |
874 | | } |
875 | | |
876 | | /// Compare the expected message sequence number `expected` with the received |
877 | | /// message sequence number `actual`. |
878 | | /// |
879 | | /// Return `()` if `actual == expected`, `Err` otherwise. |
880 | 0 | pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> crate::Result<()> { |
881 | 0 | if expected == actual { |
882 | 0 | Ok(()) |
883 | | } else { |
884 | 0 | Err(crate::Error::Application(crate::ApplicationError { |
885 | 0 | kind: crate::ApplicationErrorKind::BadSequenceId, |
886 | 0 | message: format!("expected {} got {}", expected, actual), |
887 | 0 | })) |
888 | | } |
889 | 0 | } |
890 | | |
891 | | /// Compare the expected service-call name `expected` with the received |
892 | | /// service-call name `actual`. |
893 | | /// |
894 | | /// Return `()` if `actual == expected`, `Err` otherwise. |
895 | 0 | pub fn verify_expected_service_call(expected: &str, actual: &str) -> crate::Result<()> { |
896 | 0 | if expected == actual { |
897 | 0 | Ok(()) |
898 | | } else { |
899 | 0 | Err(crate::Error::Application(crate::ApplicationError { |
900 | 0 | kind: crate::ApplicationErrorKind::WrongMethodName, |
901 | 0 | message: format!("expected {} got {}", expected, actual), |
902 | 0 | })) |
903 | | } |
904 | 0 | } |
905 | | |
906 | | /// Compare the expected message type `expected` with the received message type |
907 | | /// `actual`. |
908 | | /// |
909 | | /// Return `()` if `actual == expected`, `Err` otherwise. |
910 | 0 | pub fn verify_expected_message_type( |
911 | 0 | expected: TMessageType, |
912 | 0 | actual: TMessageType, |
913 | 0 | ) -> crate::Result<()> { |
914 | 0 | if expected == actual { |
915 | 0 | Ok(()) |
916 | | } else { |
917 | 0 | Err(crate::Error::Application(crate::ApplicationError { |
918 | 0 | kind: crate::ApplicationErrorKind::InvalidMessageType, |
919 | 0 | message: format!("expected {} got {}", expected, actual), |
920 | 0 | })) |
921 | | } |
922 | 0 | } |
923 | | |
924 | | /// Check if a required Thrift struct field exists. |
925 | | /// |
926 | | /// Return `()` if it does, `Err` otherwise. |
927 | 117k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { |
928 | 117k | match *field { |
929 | 116k | Some(_) => Ok(()), |
930 | 789 | None => Err(crate::Error::Protocol(crate::ProtocolError { |
931 | 789 | kind: crate::ProtocolErrorKind::Unknown, |
932 | 789 | message: format!("missing required field {}", field_name), |
933 | 789 | })), |
934 | | } |
935 | 117k | } thrift::protocol::verify_required_field_exists::<thrift_fuzz::fuzz_test::BasicTypes> Line | Count | Source | 927 | 7.31k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { | 928 | 7.31k | match *field { | 929 | 7.01k | Some(_) => Ok(()), | 930 | 303 | None => Err(crate::Error::Protocol(crate::ProtocolError { | 931 | 303 | kind: crate::ProtocolErrorKind::Unknown, | 932 | 303 | message: format!("missing required field {}", field_name), | 933 | 303 | })), | 934 | | } | 935 | 7.31k | } |
thrift::protocol::verify_required_field_exists::<thrift_fuzz::fuzz_test::Containers> Line | Count | Source | 927 | 6.82k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { | 928 | 6.82k | match *field { | 929 | 6.74k | Some(_) => Ok(()), | 930 | 80 | None => Err(crate::Error::Protocol(crate::ProtocolError { | 931 | 80 | kind: crate::ProtocolErrorKind::Unknown, | 932 | 80 | message: format!("missing required field {}", field_name), | 933 | 80 | })), | 934 | | } | 935 | 6.82k | } |
thrift::protocol::verify_required_field_exists::<thrift_fuzz::fuzz_test::Requiredness> Line | Count | Source | 927 | 7.01k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { | 928 | 7.01k | match *field { | 929 | 6.82k | Some(_) => Ok(()), | 930 | 188 | None => Err(crate::Error::Protocol(crate::ProtocolError { | 931 | 188 | kind: crate::ProtocolErrorKind::Unknown, | 932 | 188 | message: format!("missing required field {}", field_name), | 933 | 188 | })), | 934 | | } | 935 | 7.01k | } |
thrift::protocol::verify_required_field_exists::<thrift_fuzz::fuzz_test::TestEnum> Line | Count | Source | 927 | 6.68k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { | 928 | 6.68k | match *field { | 929 | 6.63k | Some(_) => Ok(()), | 930 | 47 | None => Err(crate::Error::Protocol(crate::ProtocolError { | 931 | 47 | kind: crate::ProtocolErrorKind::Unknown, | 932 | 47 | message: format!("missing required field {}", field_name), | 933 | 47 | })), | 934 | | } | 935 | 6.68k | } |
thrift::protocol::verify_required_field_exists::<thrift_fuzz::fuzz_test::TestUnion> Line | Count | Source | 927 | 6.74k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { | 928 | 6.74k | match *field { | 929 | 6.68k | Some(_) => Ok(()), | 930 | 63 | None => Err(crate::Error::Protocol(crate::ProtocolError { | 931 | 63 | kind: crate::ProtocolErrorKind::Unknown, | 932 | 63 | message: format!("missing required field {}", field_name), | 933 | 63 | })), | 934 | | } | 935 | 6.74k | } |
thrift::protocol::verify_required_field_exists::<bool> Line | Count | Source | 927 | 41.2k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { | 928 | 41.2k | match *field { | 929 | 41.1k | Some(_) => Ok(()), | 930 | 39 | None => Err(crate::Error::Protocol(crate::ProtocolError { | 931 | 39 | kind: crate::ProtocolErrorKind::Unknown, | 932 | 39 | message: format!("missing required field {}", field_name), | 933 | 39 | })), | 934 | | } | 935 | 41.2k | } |
thrift::protocol::verify_required_field_exists::<i32> Line | Count | Source | 927 | 41.2k | pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> { | 928 | 41.2k | match *field { | 929 | 41.2k | Some(_) => Ok(()), | 930 | 69 | None => Err(crate::Error::Protocol(crate::ProtocolError { | 931 | 69 | kind: crate::ProtocolErrorKind::Unknown, | 932 | 69 | message: format!("missing required field {}", field_name), | 933 | 69 | })), | 934 | | } | 935 | 41.2k | } |
|
936 | | |
937 | | /// Common container size validation used by all protocols. |
938 | | /// |
939 | | /// Checks that: |
940 | | /// - Container size is not negative |
941 | | /// - Container size doesn't exceed configured maximum |
942 | | /// - Container size * element size doesn't overflow |
943 | | /// - Container memory requirements don't exceed message size limit |
944 | 3.48M | pub(crate) fn check_container_size( |
945 | 3.48M | config: &TConfiguration, |
946 | 3.48M | container_size: i32, |
947 | 3.48M | element_size: usize, |
948 | 3.48M | ) -> crate::Result<()> { |
949 | | // Check for negative size |
950 | 3.48M | if container_size < 0 { |
951 | 139 | return Err(crate::Error::Protocol(ProtocolError::new( |
952 | 139 | ProtocolErrorKind::NegativeSize, |
953 | 139 | format!("Negative container size: {}", container_size), |
954 | 139 | ))); |
955 | 3.48M | } |
956 | | |
957 | 3.48M | let size_as_usize = container_size as usize; |
958 | | |
959 | | // Check against configured max container size |
960 | 3.48M | if let Some(max_size) = config.max_container_size() { |
961 | 3.48M | if size_as_usize > max_size { |
962 | 209 | return Err(crate::Error::Protocol(ProtocolError::new( |
963 | 209 | ProtocolErrorKind::SizeLimit, |
964 | 209 | format!( |
965 | 209 | "Container size {} exceeds maximum allowed size of {}", |
966 | 209 | container_size, max_size |
967 | 209 | ), |
968 | 209 | ))); |
969 | 3.48M | } |
970 | 0 | } |
971 | | |
972 | | // Check for potential overflow |
973 | 3.48M | if let Some(min_bytes_needed) = size_as_usize.checked_mul(element_size) { |
974 | | // TODO: When Rust trait specialization stabilizes, we can add more precise checks |
975 | | // for transports that track exact remaining bytes. For now, we use the message |
976 | | // size limit as a best-effort check. |
977 | 3.48M | if let Some(max_message_size) = config.max_message_size() { |
978 | 3.48M | if min_bytes_needed > max_message_size { |
979 | 156 | return Err(crate::Error::Protocol(ProtocolError::new( |
980 | 156 | ProtocolErrorKind::SizeLimit, |
981 | 156 | format!( |
982 | 156 | "Container would require {} bytes, exceeding message size limit of {}", |
983 | 156 | min_bytes_needed, max_message_size |
984 | 156 | ), |
985 | 156 | ))); |
986 | 3.47M | } |
987 | 0 | } |
988 | 3.47M | Ok(()) |
989 | | } else { |
990 | 0 | Err(crate::Error::Protocol(ProtocolError::new( |
991 | 0 | ProtocolErrorKind::SizeLimit, |
992 | 0 | format!( |
993 | 0 | "Container size {} with element size {} bytes would result in overflow", |
994 | 0 | container_size, element_size |
995 | 0 | ), |
996 | 0 | ))) |
997 | | } |
998 | 3.48M | } |
999 | | |
1000 | | /// Extract the field id from a Thrift field identifier. |
1001 | | /// |
1002 | | /// `field_ident` must *not* have `TFieldIdentifier.field_type` of type `TType::Stop`. |
1003 | | /// |
1004 | | /// Return `TFieldIdentifier.id` if an id exists, `Err` otherwise. |
1005 | 7.78M | pub fn field_id(field_ident: &TFieldIdentifier) -> crate::Result<i16> { |
1006 | 7.78M | field_ident.id.ok_or_else(|| { |
1007 | 0 | crate::Error::Protocol(crate::ProtocolError { |
1008 | 0 | kind: crate::ProtocolErrorKind::Unknown, |
1009 | 0 | message: format!("missing field id in {:?}", field_ident), |
1010 | 0 | }) |
1011 | 0 | }) |
1012 | 7.78M | } |
1013 | | |
1014 | | #[cfg(test)] |
1015 | | mod tests { |
1016 | | |
1017 | | use std::io::Cursor; |
1018 | | |
1019 | | use super::*; |
1020 | | use crate::transport::{TReadTransport, TWriteTransport}; |
1021 | | |
1022 | | #[test] |
1023 | | fn must_create_usable_input_protocol_from_concrete_input_protocol() { |
1024 | | let r: Box<dyn TReadTransport> = Box::new(Cursor::new([0, 1, 2])); |
1025 | | let mut t = TCompactInputProtocol::new(r); |
1026 | | takes_input_protocol(&mut t) |
1027 | | } |
1028 | | |
1029 | | #[test] |
1030 | | fn must_create_usable_input_protocol_from_boxed_input() { |
1031 | | let r: Box<dyn TReadTransport> = Box::new(Cursor::new([0, 1, 2])); |
1032 | | let mut t: Box<dyn TInputProtocol> = Box::new(TCompactInputProtocol::new(r)); |
1033 | | takes_input_protocol(&mut t) |
1034 | | } |
1035 | | |
1036 | | #[test] |
1037 | | fn must_create_usable_output_protocol_from_concrete_output_protocol() { |
1038 | | let w: Box<dyn TWriteTransport> = Box::new(vec![0u8; 10]); |
1039 | | let mut t = TCompactOutputProtocol::new(w); |
1040 | | takes_output_protocol(&mut t) |
1041 | | } |
1042 | | |
1043 | | #[test] |
1044 | | fn must_create_usable_output_protocol_from_boxed_output() { |
1045 | | let w: Box<dyn TWriteTransport> = Box::new(vec![0u8; 10]); |
1046 | | let mut t: Box<dyn TOutputProtocol> = Box::new(TCompactOutputProtocol::new(w)); |
1047 | | takes_output_protocol(&mut t) |
1048 | | } |
1049 | | |
1050 | | fn takes_input_protocol<R>(t: &mut R) |
1051 | | where |
1052 | | R: TInputProtocol, |
1053 | | { |
1054 | | t.read_byte().unwrap(); |
1055 | | } |
1056 | | |
1057 | | fn takes_output_protocol<W>(t: &mut W) |
1058 | | where |
1059 | | W: TOutputProtocol, |
1060 | | { |
1061 | | t.flush().unwrap(); |
1062 | | } |
1063 | | } |