Coverage Report

Created: 2026-02-26 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}