blob: 0fbf509369e8e0f7e22bd912bd1adcea3b2f0f92 [file] [log] [blame]
Allen George8b96bfb2016-11-02 08:01:08 -04001// 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//!
Allen George8b96bfb2016-11-02 08:01:08 -040022//! Create and use a `TInputProtocol`.
23//!
24//! ```no_run
Allen George8b96bfb2016-11-02 08:01:08 -040025//! use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
Allen George0e22c362017-01-30 07:15:00 -050026//! use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -040027//!
28//! // create the I/O channel
Allen George0e22c362017-01-30 07:15:00 -050029//! let mut channel = TTcpChannel::new();
30//! channel.open("127.0.0.1:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -040031//!
32//! // create the protocol to decode bytes into types
Allen George0e22c362017-01-30 07:15:00 -050033//! let mut protocol = TBinaryInputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -040034//!
35//! // read types from the wire
Allen George0e22c362017-01-30 07:15:00 -050036//! 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();
Allen George8b96bfb2016-11-02 08:01:08 -040058//! ```
59
Danny Browningddec4312019-03-08 14:20:41 -070060use std::convert::{From, TryFrom};
Allen George8b96bfb2016-11-02 08:01:08 -040061use std::fmt;
62use std::fmt::{Display, Formatter};
Allen George8b96bfb2016-11-02 08:01:08 -040063
Allen Georgeb0d14132020-03-29 11:48:55 -040064use crate::transport::{TReadTransport, TWriteTransport};
Hasnain Lakhani42d0b712025-07-17 19:57:05 -070065use crate::{ProtocolError, ProtocolErrorKind, TConfiguration};
Allen George0e22c362017-01-30 07:15:00 -050066
67#[cfg(test)]
68macro_rules! assert_eq_written_bytes {
Allen Georgeef7a1892018-12-16 18:01:37 -050069 ($o_prot:ident, $expected_bytes:ident) => {{
70 assert_eq!($o_prot.transport.write_bytes(), &$expected_bytes);
71 }};
Allen George0e22c362017-01-30 07:15:00 -050072}
73
74// FIXME: should take both read and write
75#[cfg(test)]
76macro_rules! copy_write_buffer_to_read_buffer {
Allen Georgeef7a1892018-12-16 18:01:37 -050077 ($o_prot:ident) => {{
78 $o_prot.transport.copy_write_buffer_to_read_buffer();
79 }};
Allen George0e22c362017-01-30 07:15:00 -050080}
81
82#[cfg(test)]
83macro_rules! set_readable_bytes {
84 ($i_prot:ident, $bytes:expr) => {
85 $i_prot.transport.set_readable_bytes($bytes);
Allen Georgeef7a1892018-12-16 18:01:37 -050086 };
Allen George0e22c362017-01-30 07:15:00 -050087}
Allen George8b96bfb2016-11-02 08:01:08 -040088
89mod binary;
90mod compact;
91mod multiplexed;
92mod stored;
93
Allen Georgeef7a1892018-12-16 18:01:37 -050094pub use self::binary::{
95 TBinaryInputProtocol, TBinaryInputProtocolFactory, TBinaryOutputProtocol,
96 TBinaryOutputProtocolFactory,
97};
98pub use self::compact::{
99 TCompactInputProtocol, TCompactInputProtocolFactory, TCompactOutputProtocol,
100 TCompactOutputProtocolFactory,
101};
Allen George8b96bfb2016-11-02 08:01:08 -0400102pub use self::multiplexed::TMultiplexedOutputProtocol;
103pub use self::stored::TStoredInputProtocol;
104
Zachary Kuhn2e0a8052022-04-10 11:31:28 -0400105/// Reads and writes the struct to Thrift protocols.
106///
107/// It is implemented in generated code for Thrift `struct`, `union`, and `enum` types.
108pub 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
Allen George8b96bfb2016-11-02 08:01:08 -0400113// 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.
117const 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
Allen George8b96bfb2016-11-02 08:01:08 -0400135/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
Allen George0e22c362017-01-30 07:15:00 -0500136/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400137///
Allen George0e22c362017-01-30 07:15:00 -0500138/// let mut channel = TTcpChannel::new();
139/// channel.open("127.0.0.1:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400140///
Allen George0e22c362017-01-30 07:15:00 -0500141/// let mut protocol = TBinaryInputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -0400142///
Allen George0e22c362017-01-30 07:15:00 -0500143/// 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();
Allen George8b96bfb2016-11-02 08:01:08 -0400146/// ```
147pub trait TInputProtocol {
148 /// Read the beginning of a Thrift message.
Allen Georgeb0d14132020-03-29 11:48:55 -0400149 fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier>;
Allen George8b96bfb2016-11-02 08:01:08 -0400150 /// Read the end of a Thrift message.
Allen Georgeb0d14132020-03-29 11:48:55 -0400151 fn read_message_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400152 /// Read the beginning of a Thrift struct.
Allen Georgeb0d14132020-03-29 11:48:55 -0400153 fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>>;
Allen George8b96bfb2016-11-02 08:01:08 -0400154 /// Read the end of a Thrift struct.
Allen Georgeb0d14132020-03-29 11:48:55 -0400155 fn read_struct_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400156 /// Read the beginning of a Thrift struct field.
Allen Georgeb0d14132020-03-29 11:48:55 -0400157 fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier>;
Allen George8b96bfb2016-11-02 08:01:08 -0400158 /// Read the end of a Thrift struct field.
Allen Georgeb0d14132020-03-29 11:48:55 -0400159 fn read_field_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400160 /// Read a bool.
Allen Georgeb0d14132020-03-29 11:48:55 -0400161 fn read_bool(&mut self) -> crate::Result<bool>;
Allen George8b96bfb2016-11-02 08:01:08 -0400162 /// Read a fixed-length byte array.
Allen Georgeb0d14132020-03-29 11:48:55 -0400163 fn read_bytes(&mut self) -> crate::Result<Vec<u8>>;
Allen George8b96bfb2016-11-02 08:01:08 -0400164 /// Read a word.
Allen Georgeb0d14132020-03-29 11:48:55 -0400165 fn read_i8(&mut self) -> crate::Result<i8>;
Allen George8b96bfb2016-11-02 08:01:08 -0400166 /// Read a 16-bit signed integer.
Allen Georgeb0d14132020-03-29 11:48:55 -0400167 fn read_i16(&mut self) -> crate::Result<i16>;
Allen George8b96bfb2016-11-02 08:01:08 -0400168 /// Read a 32-bit signed integer.
Allen Georgeb0d14132020-03-29 11:48:55 -0400169 fn read_i32(&mut self) -> crate::Result<i32>;
Allen George8b96bfb2016-11-02 08:01:08 -0400170 /// Read a 64-bit signed integer.
Allen Georgeb0d14132020-03-29 11:48:55 -0400171 fn read_i64(&mut self) -> crate::Result<i64>;
Allen George8b96bfb2016-11-02 08:01:08 -0400172 /// Read a 64-bit float.
Allen Georgeb0d14132020-03-29 11:48:55 -0400173 fn read_double(&mut self) -> crate::Result<f64>;
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800174 /// Read a UUID.
175 fn read_uuid(&mut self) -> crate::Result<uuid::Uuid>;
Allen George8b96bfb2016-11-02 08:01:08 -0400176 /// Read a fixed-length string (not null terminated).
Allen Georgeb0d14132020-03-29 11:48:55 -0400177 fn read_string(&mut self) -> crate::Result<String>;
Allen George8b96bfb2016-11-02 08:01:08 -0400178 /// Read the beginning of a list.
Allen Georgeb0d14132020-03-29 11:48:55 -0400179 fn read_list_begin(&mut self) -> crate::Result<TListIdentifier>;
Allen George8b96bfb2016-11-02 08:01:08 -0400180 /// Read the end of a list.
Allen Georgeb0d14132020-03-29 11:48:55 -0400181 fn read_list_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400182 /// Read the beginning of a set.
Allen Georgeb0d14132020-03-29 11:48:55 -0400183 fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier>;
Allen George8b96bfb2016-11-02 08:01:08 -0400184 /// Read the end of a set.
Allen Georgeb0d14132020-03-29 11:48:55 -0400185 fn read_set_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400186 /// Read the beginning of a map.
Allen Georgeb0d14132020-03-29 11:48:55 -0400187 fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier>;
Allen George8b96bfb2016-11-02 08:01:08 -0400188 /// Read the end of a map.
Allen Georgeb0d14132020-03-29 11:48:55 -0400189 fn read_map_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400190 /// Skip a field with type `field_type` recursively until the default
191 /// maximum skip depth is reached.
Allen Georgeb0d14132020-03-29 11:48:55 -0400192 fn skip(&mut self, field_type: TType) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400193 self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH)
194 }
195 /// Skip a field with type `field_type` recursively up to `depth` levels.
Allen Georgeb0d14132020-03-29 11:48:55 -0400196 fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400197 if depth == 0 {
Allen Georgeb0d14132020-03-29 11:48:55 -0400198 return Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500199 kind: ProtocolErrorKind::DepthLimit,
200 message: format!("cannot parse past {:?}", field_type),
201 }));
Allen George8b96bfb2016-11-02 08:01:08 -0400202 }
203
204 match field_type {
205 TType::Bool => self.read_bool().map(|_| ()),
206 TType::I08 => self.read_i8().map(|_| ()),
207 TType::I16 => self.read_i16().map(|_| ()),
208 TType::I32 => self.read_i32().map(|_| ()),
209 TType::I64 => self.read_i64().map(|_| ()),
210 TType::Double => self.read_double().map(|_| ()),
211 TType::String => self.read_string().map(|_| ()),
Hasnain Lakhani57c5fc12025-08-02 21:12:07 -0700212 TType::Uuid => self.read_uuid().map(|_| ()),
Allen George8b96bfb2016-11-02 08:01:08 -0400213 TType::Struct => {
214 self.read_struct_begin()?;
215 loop {
216 let field_ident = self.read_field_begin()?;
217 if field_ident.field_type == TType::Stop {
218 break;
219 }
220 self.skip_till_depth(field_ident.field_type, depth - 1)?;
221 }
222 self.read_struct_end()
223 }
224 TType::List => {
225 let list_ident = self.read_list_begin()?;
226 for _ in 0..list_ident.size {
227 self.skip_till_depth(list_ident.element_type, depth - 1)?;
228 }
229 self.read_list_end()
230 }
231 TType::Set => {
232 let set_ident = self.read_set_begin()?;
233 for _ in 0..set_ident.size {
234 self.skip_till_depth(set_ident.element_type, depth - 1)?;
235 }
236 self.read_set_end()
237 }
238 TType::Map => {
239 let map_ident = self.read_map_begin()?;
240 for _ in 0..map_ident.size {
Allen George0e22c362017-01-30 07:15:00 -0500241 let key_type = map_ident
242 .key_type
Allen George8b96bfb2016-11-02 08:01:08 -0400243 .expect("non-zero sized map should contain key type");
Allen George0e22c362017-01-30 07:15:00 -0500244 let val_type = map_ident
245 .value_type
Allen George8b96bfb2016-11-02 08:01:08 -0400246 .expect("non-zero sized map should contain value type");
247 self.skip_till_depth(key_type, depth - 1)?;
248 self.skip_till_depth(val_type, depth - 1)?;
249 }
250 self.read_map_end()
251 }
Allen Georgeb0d14132020-03-29 11:48:55 -0400252 u => Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500253 kind: ProtocolErrorKind::Unknown,
254 message: format!("cannot skip field type {:?}", &u),
255 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400256 }
257 }
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.
Allen Georgeb0d14132020-03-29 11:48:55 -0400265 fn read_byte(&mut self) -> crate::Result<u8>;
Hasnain Lakhani42d0b712025-07-17 19:57:05 -0700266
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 fn min_serialized_size(&self, field_type: TType) -> usize {
273 self::compact::compact_protocol_min_serialized_size(field_type)
274 }
Allen George8b96bfb2016-11-02 08:01:08 -0400275}
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
Allen George8b96bfb2016-11-02 08:01:08 -0400296/// use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType};
Allen George0e22c362017-01-30 07:15:00 -0500297/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400298///
Allen George0e22c362017-01-30 07:15:00 -0500299/// let mut channel = TTcpChannel::new();
300/// channel.open("127.0.0.1:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400301///
Allen George0e22c362017-01-30 07:15:00 -0500302/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
Allen George8b96bfb2016-11-02 08:01:08 -0400303///
Allen George0e22c362017-01-30 07:15:00 -0500304/// protocol.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap();
305/// protocol.write_string("foo").unwrap();
306/// protocol.write_field_end().unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400307/// ```
308pub trait TOutputProtocol {
309 /// Write the beginning of a Thrift message.
Allen Georgeb0d14132020-03-29 11:48:55 -0400310 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400311 /// Write the end of a Thrift message.
Allen Georgeb0d14132020-03-29 11:48:55 -0400312 fn write_message_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400313 /// Write the beginning of a Thrift struct.
Allen Georgeb0d14132020-03-29 11:48:55 -0400314 fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400315 /// Write the end of a Thrift struct.
Allen Georgeb0d14132020-03-29 11:48:55 -0400316 fn write_struct_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400317 /// Write the beginning of a Thrift field.
Allen Georgeb0d14132020-03-29 11:48:55 -0400318 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400319 /// Write the end of a Thrift field.
Allen Georgeb0d14132020-03-29 11:48:55 -0400320 fn write_field_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400321 /// Write a STOP field indicating that all the fields in a struct have been
322 /// written.
Allen Georgeb0d14132020-03-29 11:48:55 -0400323 fn write_field_stop(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400324 /// Write a bool.
Allen Georgeb0d14132020-03-29 11:48:55 -0400325 fn write_bool(&mut self, b: bool) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400326 /// Write a fixed-length byte array.
Allen Georgeb0d14132020-03-29 11:48:55 -0400327 fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400328 /// Write an 8-bit signed integer.
Allen Georgeb0d14132020-03-29 11:48:55 -0400329 fn write_i8(&mut self, i: i8) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400330 /// Write a 16-bit signed integer.
Allen Georgeb0d14132020-03-29 11:48:55 -0400331 fn write_i16(&mut self, i: i16) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400332 /// Write a 32-bit signed integer.
Allen Georgeb0d14132020-03-29 11:48:55 -0400333 fn write_i32(&mut self, i: i32) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400334 /// Write a 64-bit signed integer.
Allen Georgeb0d14132020-03-29 11:48:55 -0400335 fn write_i64(&mut self, i: i64) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400336 /// Write a 64-bit float.
Allen Georgeb0d14132020-03-29 11:48:55 -0400337 fn write_double(&mut self, d: f64) -> crate::Result<()>;
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800338 /// Write a UUID
339 fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400340 /// Write a fixed-length string.
Allen Georgeb0d14132020-03-29 11:48:55 -0400341 fn write_string(&mut self, s: &str) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400342 /// Write the beginning of a list.
Allen Georgeb0d14132020-03-29 11:48:55 -0400343 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400344 /// Write the end of a list.
Allen Georgeb0d14132020-03-29 11:48:55 -0400345 fn write_list_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400346 /// Write the beginning of a set.
Allen Georgeb0d14132020-03-29 11:48:55 -0400347 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400348 /// Write the end of a set.
Allen Georgeb0d14132020-03-29 11:48:55 -0400349 fn write_set_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400350 /// Write the beginning of a map.
Allen Georgeb0d14132020-03-29 11:48:55 -0400351 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400352 /// Write the end of a map.
Allen Georgeb0d14132020-03-29 11:48:55 -0400353 fn write_map_end(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400354 /// Flush buffered bytes to the underlying transport.
Allen Georgeb0d14132020-03-29 11:48:55 -0400355 fn flush(&mut self) -> crate::Result<()>;
Allen George8b96bfb2016-11-02 08:01:08 -0400356
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.
Allen Georgeb0d14132020-03-29 11:48:55 -0400363 fn write_byte(&mut self, b: u8) -> crate::Result<()>; // FIXME: REMOVE
Allen George8b96bfb2016-11-02 08:01:08 -0400364}
365
Allen George0e22c362017-01-30 07:15:00 -0500366impl<P> TInputProtocol for Box<P>
367where
368 P: TInputProtocol + ?Sized,
369{
Allen Georgeb0d14132020-03-29 11:48:55 -0400370 fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500371 (**self).read_message_begin()
372 }
373
Allen Georgeb0d14132020-03-29 11:48:55 -0400374 fn read_message_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500375 (**self).read_message_end()
376 }
377
Allen Georgeb0d14132020-03-29 11:48:55 -0400378 fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
Allen George0e22c362017-01-30 07:15:00 -0500379 (**self).read_struct_begin()
380 }
381
Allen Georgeb0d14132020-03-29 11:48:55 -0400382 fn read_struct_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500383 (**self).read_struct_end()
384 }
385
Allen Georgeb0d14132020-03-29 11:48:55 -0400386 fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500387 (**self).read_field_begin()
388 }
389
Allen Georgeb0d14132020-03-29 11:48:55 -0400390 fn read_field_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500391 (**self).read_field_end()
392 }
393
Allen Georgeb0d14132020-03-29 11:48:55 -0400394 fn read_bool(&mut self) -> crate::Result<bool> {
Allen George0e22c362017-01-30 07:15:00 -0500395 (**self).read_bool()
396 }
397
Allen Georgeb0d14132020-03-29 11:48:55 -0400398 fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
Allen George0e22c362017-01-30 07:15:00 -0500399 (**self).read_bytes()
400 }
401
Allen Georgeb0d14132020-03-29 11:48:55 -0400402 fn read_i8(&mut self) -> crate::Result<i8> {
Allen George0e22c362017-01-30 07:15:00 -0500403 (**self).read_i8()
404 }
405
Allen Georgeb0d14132020-03-29 11:48:55 -0400406 fn read_i16(&mut self) -> crate::Result<i16> {
Allen George0e22c362017-01-30 07:15:00 -0500407 (**self).read_i16()
408 }
409
Allen Georgeb0d14132020-03-29 11:48:55 -0400410 fn read_i32(&mut self) -> crate::Result<i32> {
Allen George0e22c362017-01-30 07:15:00 -0500411 (**self).read_i32()
412 }
413
Allen Georgeb0d14132020-03-29 11:48:55 -0400414 fn read_i64(&mut self) -> crate::Result<i64> {
Allen George0e22c362017-01-30 07:15:00 -0500415 (**self).read_i64()
416 }
417
Allen Georgeb0d14132020-03-29 11:48:55 -0400418 fn read_double(&mut self) -> crate::Result<f64> {
Allen George0e22c362017-01-30 07:15:00 -0500419 (**self).read_double()
420 }
421
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800422 fn read_uuid(&mut self) -> crate::Result<uuid::Uuid> {
423 (**self).read_uuid()
424 }
425
Allen Georgeb0d14132020-03-29 11:48:55 -0400426 fn read_string(&mut self) -> crate::Result<String> {
Allen George0e22c362017-01-30 07:15:00 -0500427 (**self).read_string()
428 }
429
Allen Georgeb0d14132020-03-29 11:48:55 -0400430 fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500431 (**self).read_list_begin()
432 }
433
Allen Georgeb0d14132020-03-29 11:48:55 -0400434 fn read_list_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500435 (**self).read_list_end()
436 }
437
Allen Georgeb0d14132020-03-29 11:48:55 -0400438 fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500439 (**self).read_set_begin()
440 }
441
Allen Georgeb0d14132020-03-29 11:48:55 -0400442 fn read_set_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500443 (**self).read_set_end()
444 }
445
Allen Georgeb0d14132020-03-29 11:48:55 -0400446 fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
Allen George0e22c362017-01-30 07:15:00 -0500447 (**self).read_map_begin()
448 }
449
Allen Georgeb0d14132020-03-29 11:48:55 -0400450 fn read_map_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500451 (**self).read_map_end()
452 }
453
Allen Georgeb0d14132020-03-29 11:48:55 -0400454 fn read_byte(&mut self) -> crate::Result<u8> {
Allen George0e22c362017-01-30 07:15:00 -0500455 (**self).read_byte()
456 }
Hasnain Lakhani42d0b712025-07-17 19:57:05 -0700457
458 fn min_serialized_size(&self, field_type: TType) -> usize {
459 (**self).min_serialized_size(field_type)
460 }
Allen George0e22c362017-01-30 07:15:00 -0500461}
462
463impl<P> TOutputProtocol for Box<P>
464where
465 P: TOutputProtocol + ?Sized,
466{
Allen Georgeb0d14132020-03-29 11:48:55 -0400467 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500468 (**self).write_message_begin(identifier)
469 }
470
Allen Georgeb0d14132020-03-29 11:48:55 -0400471 fn write_message_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500472 (**self).write_message_end()
473 }
474
Allen Georgeb0d14132020-03-29 11:48:55 -0400475 fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500476 (**self).write_struct_begin(identifier)
477 }
478
Allen Georgeb0d14132020-03-29 11:48:55 -0400479 fn write_struct_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500480 (**self).write_struct_end()
481 }
482
Allen Georgeb0d14132020-03-29 11:48:55 -0400483 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500484 (**self).write_field_begin(identifier)
485 }
486
Allen Georgeb0d14132020-03-29 11:48:55 -0400487 fn write_field_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500488 (**self).write_field_end()
489 }
490
Allen Georgeb0d14132020-03-29 11:48:55 -0400491 fn write_field_stop(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500492 (**self).write_field_stop()
493 }
494
Allen Georgeb0d14132020-03-29 11:48:55 -0400495 fn write_bool(&mut self, b: bool) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500496 (**self).write_bool(b)
497 }
498
Allen Georgeb0d14132020-03-29 11:48:55 -0400499 fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500500 (**self).write_bytes(b)
501 }
502
Allen Georgeb0d14132020-03-29 11:48:55 -0400503 fn write_i8(&mut self, i: i8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500504 (**self).write_i8(i)
505 }
506
Allen Georgeb0d14132020-03-29 11:48:55 -0400507 fn write_i16(&mut self, i: i16) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500508 (**self).write_i16(i)
509 }
510
Allen Georgeb0d14132020-03-29 11:48:55 -0400511 fn write_i32(&mut self, i: i32) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500512 (**self).write_i32(i)
513 }
514
Allen Georgeb0d14132020-03-29 11:48:55 -0400515 fn write_i64(&mut self, i: i64) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500516 (**self).write_i64(i)
517 }
518
Allen Georgeb0d14132020-03-29 11:48:55 -0400519 fn write_double(&mut self, d: f64) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500520 (**self).write_double(d)
521 }
522
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800523 fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()> {
524 (**self).write_uuid(uuid)
525 }
526
Allen Georgeb0d14132020-03-29 11:48:55 -0400527 fn write_string(&mut self, s: &str) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500528 (**self).write_string(s)
529 }
530
Allen Georgeb0d14132020-03-29 11:48:55 -0400531 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500532 (**self).write_list_begin(identifier)
533 }
534
Allen Georgeb0d14132020-03-29 11:48:55 -0400535 fn write_list_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500536 (**self).write_list_end()
537 }
538
Allen Georgeb0d14132020-03-29 11:48:55 -0400539 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500540 (**self).write_set_begin(identifier)
541 }
542
Allen Georgeb0d14132020-03-29 11:48:55 -0400543 fn write_set_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500544 (**self).write_set_end()
545 }
546
Allen Georgeb0d14132020-03-29 11:48:55 -0400547 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500548 (**self).write_map_begin(identifier)
549 }
550
Allen Georgeb0d14132020-03-29 11:48:55 -0400551 fn write_map_end(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500552 (**self).write_map_end()
553 }
554
Allen Georgeb0d14132020-03-29 11:48:55 -0400555 fn flush(&mut self) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500556 (**self).flush()
557 }
558
Allen Georgeb0d14132020-03-29 11:48:55 -0400559 fn write_byte(&mut self, b: u8) -> crate::Result<()> {
Allen George0e22c362017-01-30 07:15:00 -0500560 (**self).write_byte(b)
561 }
562}
563
Allen George8b96bfb2016-11-02 08:01:08 -0400564/// 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
Allen George8b96bfb2016-11-02 08:01:08 -0400572/// use thrift::protocol::{TBinaryInputProtocolFactory, TInputProtocolFactory};
Allen George0e22c362017-01-30 07:15:00 -0500573/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400574///
Allen George0e22c362017-01-30 07:15:00 -0500575/// let mut channel = TTcpChannel::new();
576/// channel.open("127.0.0.1:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400577///
Allen George0e22c362017-01-30 07:15:00 -0500578/// let factory = TBinaryInputProtocolFactory::new();
579/// let protocol = factory.create(Box::new(channel));
Allen George8b96bfb2016-11-02 08:01:08 -0400580/// ```
581pub trait TInputProtocolFactory {
Hasnain Lakhani42d0b712025-07-17 19:57:05 -0700582 /// Create a `TInputProtocol` that reads bytes from `transport`.
Danny Browning77d96c12019-08-21 13:41:07 -0600583 fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send>;
Allen George0e22c362017-01-30 07:15:00 -0500584}
585
586impl<T> TInputProtocolFactory for Box<T>
587where
588 T: TInputProtocolFactory + ?Sized,
589{
Danny Browning77d96c12019-08-21 13:41:07 -0600590 fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500591 (**self).create(transport)
592 }
Allen George8b96bfb2016-11-02 08:01:08 -0400593}
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
Allen George8b96bfb2016-11-02 08:01:08 -0400603/// use thrift::protocol::{TBinaryOutputProtocolFactory, TOutputProtocolFactory};
Allen George0e22c362017-01-30 07:15:00 -0500604/// use thrift::transport::TTcpChannel;
Allen George8b96bfb2016-11-02 08:01:08 -0400605///
Allen George0e22c362017-01-30 07:15:00 -0500606/// let mut channel = TTcpChannel::new();
607/// channel.open("127.0.0.1:9090").unwrap();
Allen George8b96bfb2016-11-02 08:01:08 -0400608///
Allen George0e22c362017-01-30 07:15:00 -0500609/// let factory = TBinaryOutputProtocolFactory::new();
610/// let protocol = factory.create(Box::new(channel));
Allen George8b96bfb2016-11-02 08:01:08 -0400611/// ```
612pub trait TOutputProtocolFactory {
613 /// Create a `TOutputProtocol` that writes bytes to `transport`.
Allen George55c3e4c2021-03-01 23:19:52 -0500614 fn create(&self, transport: Box<dyn TWriteTransport + Send>)
615 -> Box<dyn TOutputProtocol + Send>;
Allen George0e22c362017-01-30 07:15:00 -0500616}
617
618impl<T> TOutputProtocolFactory for Box<T>
619where
620 T: TOutputProtocolFactory + ?Sized,
621{
Allen George55c3e4c2021-03-01 23:19:52 -0500622 fn create(
623 &self,
624 transport: Box<dyn TWriteTransport + Send>,
625 ) -> Box<dyn TOutputProtocol + Send> {
Allen George0e22c362017-01-30 07:15:00 -0500626 (**self).create(transport)
627 }
Allen George8b96bfb2016-11-02 08:01:08 -0400628}
629
630/// Thrift message identifier.
631#[derive(Clone, Debug, Eq, PartialEq)]
632pub 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
641impl TMessageIdentifier {
642 /// Create a `TMessageIdentifier` for a Thrift service-call named `name`
643 /// with message type `message_type` and sequence number `sequence_number`.
Allen George0e22c362017-01-30 07:15:00 -0500644 pub fn new<S: Into<String>>(
645 name: S,
646 message_type: TMessageType,
647 sequence_number: i32,
648 ) -> TMessageIdentifier {
Allen George8b96bfb2016-11-02 08:01:08 -0400649 TMessageIdentifier {
650 name: name.into(),
Allen George7ddbcc02020-11-08 09:51:19 -0500651 message_type,
652 sequence_number,
Allen George8b96bfb2016-11-02 08:01:08 -0400653 }
654 }
655}
656
657/// Thrift struct identifier.
658#[derive(Clone, Debug, Eq, PartialEq)]
659pub struct TStructIdentifier {
660 /// Name of the encoded Thrift struct.
661 pub name: String,
662}
663
664impl TStructIdentifier {
665 /// Create a `TStructIdentifier` for a struct named `name`.
666 pub fn new<S: Into<String>>(name: S) -> TStructIdentifier {
667 TStructIdentifier { name: name.into() }
668 }
669}
670
671/// Thrift field identifier.
672#[derive(Clone, Debug, Eq, PartialEq)]
673pub 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
688impl 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 pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier
Allen George0e22c362017-01-30 07:15:00 -0500694 where
695 N: Into<Option<S>>,
696 S: Into<String>,
697 I: Into<Option<i16>>,
Allen George8b96bfb2016-11-02 08:01:08 -0400698 {
699 TFieldIdentifier {
700 name: name.into().map(|n| n.into()),
Allen George7ddbcc02020-11-08 09:51:19 -0500701 field_type,
Allen George8b96bfb2016-11-02 08:01:08 -0400702 id: id.into(),
703 }
704 }
705}
706
707/// Thrift list identifier.
708#[derive(Clone, Debug, Eq, PartialEq)]
709pub 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
716impl TListIdentifier {
717 /// Create a `TListIdentifier` for a list with `size` elements of type
718 /// `element_type`.
719 pub fn new(element_type: TType, size: i32) -> TListIdentifier {
Allen George55c3e4c2021-03-01 23:19:52 -0500720 TListIdentifier { element_type, size }
Allen George8b96bfb2016-11-02 08:01:08 -0400721 }
722}
723
724/// Thrift set identifier.
725#[derive(Clone, Debug, Eq, PartialEq)]
726pub 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
733impl TSetIdentifier {
734 /// Create a `TSetIdentifier` for a set with `size` elements of type
735 /// `element_type`.
736 pub fn new(element_type: TType, size: i32) -> TSetIdentifier {
Allen George55c3e4c2021-03-01 23:19:52 -0500737 TSetIdentifier { element_type, size }
Allen George8b96bfb2016-11-02 08:01:08 -0400738 }
739}
740
741/// Thrift map identifier.
742#[derive(Clone, Debug, Eq, PartialEq)]
743pub 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
752impl TMapIdentifier {
753 /// Create a `TMapIdentifier` for a map with `size` entries of type
754 /// `key_type -> value_type`.
755 pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier
Allen George0e22c362017-01-30 07:15:00 -0500756 where
757 K: Into<Option<TType>>,
758 V: Into<Option<TType>>,
Allen George8b96bfb2016-11-02 08:01:08 -0400759 {
760 TMapIdentifier {
761 key_type: key_type.into(),
762 value_type: value_type.into(),
Allen George7ddbcc02020-11-08 09:51:19 -0500763 size,
Allen George8b96bfb2016-11-02 08:01:08 -0400764 }
765 }
766}
767
768/// Thrift message types.
769#[derive(Clone, Copy, Debug, Eq, PartialEq)]
770pub 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
781impl Display for TMessageType {
Allen George7ddbcc02020-11-08 09:51:19 -0500782 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Allen George8b96bfb2016-11-02 08:01:08 -0400783 match *self {
784 TMessageType::Call => write!(f, "Call"),
785 TMessageType::Reply => write!(f, "Reply"),
786 TMessageType::Exception => write!(f, "Exception"),
787 TMessageType::OneWay => write!(f, "OneWay"),
788 }
789 }
790}
791
792impl From<TMessageType> for u8 {
793 fn from(message_type: TMessageType) -> Self {
794 match message_type {
795 TMessageType::Call => 0x01,
796 TMessageType::Reply => 0x02,
797 TMessageType::Exception => 0x03,
798 TMessageType::OneWay => 0x04,
799 }
800 }
801}
802
803impl TryFrom<u8> for TMessageType {
Allen Georgeb0d14132020-03-29 11:48:55 -0400804 type Error = crate::Error;
Danny Browningddec4312019-03-08 14:20:41 -0700805 fn try_from(b: u8) -> Result<Self, Self::Error> {
Allen George8b96bfb2016-11-02 08:01:08 -0400806 match b {
807 0x01 => Ok(TMessageType::Call),
808 0x02 => Ok(TMessageType::Reply),
809 0x03 => Ok(TMessageType::Exception),
810 0x04 => Ok(TMessageType::OneWay),
Allen Georgeb0d14132020-03-29 11:48:55 -0400811 unkn => Err(crate::Error::Protocol(ProtocolError {
Allen Georgeef7a1892018-12-16 18:01:37 -0500812 kind: ProtocolErrorKind::InvalidData,
813 message: format!("cannot convert {} to TMessageType", unkn),
814 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400815 }
816 }
817}
818
819/// Thrift struct-field types.
820#[derive(Clone, Copy, Debug, Eq, PartialEq)]
821pub 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,
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800850 /// Uuid.
851 Uuid,
Allen George8b96bfb2016-11-02 08:01:08 -0400852}
853
854impl Display for TType {
Allen George7ddbcc02020-11-08 09:51:19 -0500855 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Allen George8b96bfb2016-11-02 08:01:08 -0400856 match *self {
857 TType::Stop => write!(f, "STOP"),
858 TType::Void => write!(f, "void"),
859 TType::Bool => write!(f, "bool"),
860 TType::I08 => write!(f, "i08"),
861 TType::Double => write!(f, "double"),
862 TType::I16 => write!(f, "i16"),
863 TType::I32 => write!(f, "i32"),
864 TType::I64 => write!(f, "i64"),
865 TType::String => write!(f, "string"),
866 TType::Utf7 => write!(f, "UTF7"),
867 TType::Struct => write!(f, "struct"),
868 TType::Map => write!(f, "map"),
869 TType::Set => write!(f, "set"),
870 TType::List => write!(f, "list"),
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800871 TType::Uuid => write!(f, "UUID"),
Allen George8b96bfb2016-11-02 08:01:08 -0400872 }
873 }
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.
Allen Georgeb0d14132020-03-29 11:48:55 -0400880pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400881 if expected == actual {
882 Ok(())
883 } else {
Allen Georgeb0d14132020-03-29 11:48:55 -0400884 Err(crate::Error::Application(crate::ApplicationError {
885 kind: crate::ApplicationErrorKind::BadSequenceId,
Allen Georgeef7a1892018-12-16 18:01:37 -0500886 message: format!("expected {} got {}", expected, actual),
887 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400888 }
889}
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.
Allen Georgeb0d14132020-03-29 11:48:55 -0400895pub fn verify_expected_service_call(expected: &str, actual: &str) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400896 if expected == actual {
897 Ok(())
898 } else {
Allen Georgeb0d14132020-03-29 11:48:55 -0400899 Err(crate::Error::Application(crate::ApplicationError {
900 kind: crate::ApplicationErrorKind::WrongMethodName,
Allen Georgeef7a1892018-12-16 18:01:37 -0500901 message: format!("expected {} got {}", expected, actual),
902 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400903 }
904}
905
906/// Compare the expected message type `expected` with the received message type
907/// `actual`.
908///
909/// Return `()` if `actual == expected`, `Err` otherwise.
Allen George55c3e4c2021-03-01 23:19:52 -0500910pub fn verify_expected_message_type(
911 expected: TMessageType,
912 actual: TMessageType,
913) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400914 if expected == actual {
915 Ok(())
916 } else {
Allen Georgeb0d14132020-03-29 11:48:55 -0400917 Err(crate::Error::Application(crate::ApplicationError {
918 kind: crate::ApplicationErrorKind::InvalidMessageType,
Allen Georgeef7a1892018-12-16 18:01:37 -0500919 message: format!("expected {} got {}", expected, actual),
920 }))
Allen George8b96bfb2016-11-02 08:01:08 -0400921 }
922}
923
924/// Check if a required Thrift struct field exists.
925///
926/// Return `()` if it does, `Err` otherwise.
Allen Georgeb0d14132020-03-29 11:48:55 -0400927pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400928 match *field {
929 Some(_) => Ok(()),
Allen Georgeb0d14132020-03-29 11:48:55 -0400930 None => Err(crate::Error::Protocol(crate::ProtocolError {
931 kind: crate::ProtocolErrorKind::Unknown,
Allen Georgeef7a1892018-12-16 18:01:37 -0500932 message: format!("missing required field {}", field_name),
933 })),
Allen George8b96bfb2016-11-02 08:01:08 -0400934 }
935}
936
Hasnain Lakhani42d0b712025-07-17 19:57:05 -0700937/// 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
944pub(crate) fn check_container_size(
945 config: &TConfiguration,
946 container_size: i32,
947 element_size: usize,
948) -> crate::Result<()> {
949 // Check for negative size
950 if container_size < 0 {
951 return Err(crate::Error::Protocol(ProtocolError::new(
952 ProtocolErrorKind::NegativeSize,
953 format!("Negative container size: {}", container_size),
954 )));
955 }
956
957 let size_as_usize = container_size as usize;
958
959 // Check against configured max container size
960 if let Some(max_size) = config.max_container_size() {
961 if size_as_usize > max_size {
962 return Err(crate::Error::Protocol(ProtocolError::new(
963 ProtocolErrorKind::SizeLimit,
964 format!(
965 "Container size {} exceeds maximum allowed size of {}",
966 container_size, max_size
967 ),
968 )));
969 }
970 }
971
972 // Check for potential overflow
973 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 if let Some(max_message_size) = config.max_message_size() {
978 if min_bytes_needed > max_message_size {
979 return Err(crate::Error::Protocol(ProtocolError::new(
980 ProtocolErrorKind::SizeLimit,
981 format!(
982 "Container would require {} bytes, exceeding message size limit of {}",
983 min_bytes_needed, max_message_size
984 ),
985 )));
986 }
987 }
988 Ok(())
989 } else {
990 Err(crate::Error::Protocol(ProtocolError::new(
991 ProtocolErrorKind::SizeLimit,
992 format!(
993 "Container size {} with element size {} bytes would result in overflow",
994 container_size, element_size
995 ),
996 )))
997 }
998}
999
Allen George8b96bfb2016-11-02 08:01:08 -04001000/// 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.
Allen Georgeb0d14132020-03-29 11:48:55 -04001005pub fn field_id(field_ident: &TFieldIdentifier) -> crate::Result<i16> {
Allen Georgeef7a1892018-12-16 18:01:37 -05001006 field_ident.id.ok_or_else(|| {
Allen Georgeb0d14132020-03-29 11:48:55 -04001007 crate::Error::Protocol(crate::ProtocolError {
1008 kind: crate::ProtocolErrorKind::Unknown,
60067815d642022-09-01 16:05:12 +08001009 message: format!("missing field id in {:?}", field_ident),
Allen Georgeef7a1892018-12-16 18:01:37 -05001010 })
1011 })
Allen George0e22c362017-01-30 07:15:00 -05001012}
1013
1014#[cfg(test)]
1015mod tests {
1016
1017 use std::io::Cursor;
1018
1019 use super::*;
Allen Georgeb0d14132020-03-29 11:48:55 -04001020 use crate::transport::{TReadTransport, TWriteTransport};
Allen George0e22c362017-01-30 07:15:00 -05001021
1022 #[test]
1023 fn must_create_usable_input_protocol_from_concrete_input_protocol() {
Danny Browning77d96c12019-08-21 13:41:07 -06001024 let r: Box<dyn TReadTransport> = Box::new(Cursor::new([0, 1, 2]));
Allen George0e22c362017-01-30 07:15:00 -05001025 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() {
Danny Browning77d96c12019-08-21 13:41:07 -06001031 let r: Box<dyn TReadTransport> = Box::new(Cursor::new([0, 1, 2]));
1032 let mut t: Box<dyn TInputProtocol> = Box::new(TCompactInputProtocol::new(r));
Allen George0e22c362017-01-30 07:15:00 -05001033 takes_input_protocol(&mut t)
1034 }
1035
1036 #[test]
1037 fn must_create_usable_output_protocol_from_concrete_output_protocol() {
Danny Browning77d96c12019-08-21 13:41:07 -06001038 let w: Box<dyn TWriteTransport> = Box::new(vec![0u8; 10]);
Allen George0e22c362017-01-30 07:15:00 -05001039 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() {
Danny Browning77d96c12019-08-21 13:41:07 -06001045 let w: Box<dyn TWriteTransport> = Box::new(vec![0u8; 10]);
1046 let mut t: Box<dyn TOutputProtocol> = Box::new(TCompactOutputProtocol::new(w));
Allen George0e22c362017-01-30 07:15:00 -05001047 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 }
Allen George8b96bfb2016-11-02 08:01:08 -04001063}