parquet_format_async_temp/thrift/protocol/
mod.rs

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
60use std::convert::{From, TryFrom};
61use std::fmt;
62use std::fmt::{Display, Formatter};
63
64use crate::thrift::{ApplicationError, Error, ProtocolError, ProtocolErrorKind};
65
66mod compact;
67mod compact_stream;
68pub use compact_stream::TCompactInputStreamProtocol;
69mod compact_stream_write;
70pub use compact_stream_write::TCompactOutputStreamProtocol;
71mod stream;
72pub use stream::{TInputStreamProtocol, TOutputStreamProtocol};
73
74pub use self::compact::{TCompactInputProtocol, TCompactOutputProtocol};
75
76// Default maximum depth to which `TInputProtocol::skip` will skip a Thrift
77// field. A default is necessary because Thrift structs or collections may
78// contain nested structs and collections, which could result in indefinite
79// recursion.
80const MAXIMUM_SKIP_DEPTH: i8 = 64;
81
82/// Converts a stream of bytes into Thrift identifiers, primitives,
83/// containers, or structs.
84///
85/// This trait does not deal with higher-level Thrift concepts like structs or
86/// exceptions - only with primitives and message or container boundaries. Once
87/// bytes are read they are deserialized and an identifier (for example
88/// `TMessageIdentifier`) or a primitive is returned.
89///
90/// All methods return a `thrift::Result`. If an `Err` is returned the protocol
91/// instance and its underlying transport should be terminated.
92///
93/// # Examples
94///
95/// Create and use a `TInputProtocol`
96///
97/// ```no_run
98/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
99/// use thrift::transport::TTcpChannel;
100///
101/// let mut channel = TTcpChannel::new();
102/// channel.open("127.0.0.1:9090").unwrap();
103///
104/// let mut protocol = TBinaryInputProtocol::new(channel, true);
105///
106/// let field_identifier = protocol.read_field_begin().unwrap();
107/// let field_contents = protocol.read_string().unwrap();
108/// let field_end = protocol.read_field_end().unwrap();
109/// ```
110pub trait TInputProtocol {
111    /// Read the beginning of a Thrift message.
112    fn read_message_begin(&mut self) -> crate::thrift::Result<TMessageIdentifier>;
113    /// Read the end of a Thrift message.
114    fn read_message_end(&mut self) -> crate::thrift::Result<()>;
115    /// Read the beginning of a Thrift struct.
116    fn read_struct_begin(&mut self) -> crate::thrift::Result<Option<TStructIdentifier>>;
117    /// Read the end of a Thrift struct.
118    fn read_struct_end(&mut self) -> crate::thrift::Result<()>;
119    /// Read the beginning of a Thrift struct field.
120    fn read_field_begin(&mut self) -> crate::thrift::Result<TFieldIdentifier>;
121    /// Read the end of a Thrift struct field.
122    fn read_field_end(&mut self) -> crate::thrift::Result<()>;
123    /// Read a bool.
124    fn read_bool(&mut self) -> crate::thrift::Result<bool>;
125    /// Read a fixed-length byte array.
126    fn read_bytes(&mut self) -> crate::thrift::Result<Vec<u8>>;
127    /// Read a word.
128    fn read_i8(&mut self) -> crate::thrift::Result<i8>;
129    /// Read a 16-bit signed integer.
130    fn read_i16(&mut self) -> crate::thrift::Result<i16>;
131    /// Read a 32-bit signed integer.
132    fn read_i32(&mut self) -> crate::thrift::Result<i32>;
133    /// Read a 64-bit signed integer.
134    fn read_i64(&mut self) -> crate::thrift::Result<i64>;
135    /// Read a 64-bit float.
136    fn read_double(&mut self) -> crate::thrift::Result<f64>;
137    /// Read a fixed-length string (not null terminated).
138    fn read_string(&mut self) -> crate::thrift::Result<String>;
139    /// Read the beginning of a list.
140    fn read_list_begin(&mut self) -> crate::thrift::Result<TListIdentifier>;
141    /// Read the end of a list.
142    fn read_list_end(&mut self) -> crate::thrift::Result<()>;
143    /// Read the beginning of a set.
144    fn read_set_begin(&mut self) -> crate::thrift::Result<TSetIdentifier>;
145    /// Read the end of a set.
146    fn read_set_end(&mut self) -> crate::thrift::Result<()>;
147    /// Read the beginning of a map.
148    fn read_map_begin(&mut self) -> crate::thrift::Result<TMapIdentifier>;
149    /// Read the end of a map.
150    fn read_map_end(&mut self) -> crate::thrift::Result<()>;
151    /// Skip a field with type `field_type` recursively until the default
152    /// maximum skip depth is reached.
153    fn skip(&mut self, field_type: TType) -> crate::thrift::Result<()> {
154        self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH)
155    }
156    /// Skip a field with type `field_type` recursively up to `depth` levels.
157    fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::thrift::Result<()> {
158        if depth == 0 {
159            return Err(crate::thrift::Error::Protocol(ProtocolError {
160                kind: ProtocolErrorKind::DepthLimit,
161                message: format!("cannot parse past {:?}", field_type),
162            }));
163        }
164
165        match field_type {
166            TType::Bool => self.read_bool().map(|_| ()),
167            TType::I08 => self.read_i8().map(|_| ()),
168            TType::I16 => self.read_i16().map(|_| ()),
169            TType::I32 => self.read_i32().map(|_| ()),
170            TType::I64 => self.read_i64().map(|_| ()),
171            TType::Double => self.read_double().map(|_| ()),
172            TType::String => self.read_string().map(|_| ()),
173            TType::Struct => {
174                self.read_struct_begin()?;
175                loop {
176                    let field_ident = self.read_field_begin()?;
177                    if field_ident.field_type == TType::Stop {
178                        break;
179                    }
180                    self.skip_till_depth(field_ident.field_type, depth - 1)?;
181                }
182                self.read_struct_end()
183            }
184            TType::List => {
185                let list_ident = self.read_list_begin()?;
186                for _ in 0..list_ident.size {
187                    self.skip_till_depth(list_ident.element_type, depth - 1)?;
188                }
189                self.read_list_end()
190            }
191            TType::Set => {
192                let set_ident = self.read_set_begin()?;
193                for _ in 0..set_ident.size {
194                    self.skip_till_depth(set_ident.element_type, depth - 1)?;
195                }
196                self.read_set_end()
197            }
198            TType::Map => {
199                let map_ident = self.read_map_begin()?;
200                for _ in 0..map_ident.size {
201                    let key_type = map_ident
202                        .key_type
203                        .expect("non-zero sized map should contain key type");
204                    let val_type = map_ident
205                        .value_type
206                        .expect("non-zero sized map should contain value type");
207                    self.skip_till_depth(key_type, depth - 1)?;
208                    self.skip_till_depth(val_type, depth - 1)?;
209                }
210                self.read_map_end()
211            }
212            u => Err(crate::thrift::Error::Protocol(ProtocolError {
213                kind: ProtocolErrorKind::Unknown,
214                message: format!("cannot skip field type {:?}", &u),
215            })),
216        }
217    }
218
219    // utility (DO NOT USE IN GENERATED CODE!!!!)
220    //
221
222    /// Read an unsigned byte.
223    ///
224    /// This method should **never** be used in generated code.
225    fn read_byte(&mut self) -> crate::thrift::Result<u8>;
226}
227
228/// Converts Thrift identifiers, primitives, containers or structs into a
229/// stream of bytes.
230///
231/// This trait does not deal with higher-level Thrift concepts like structs or
232/// exceptions - only with primitives and message or container boundaries.
233/// Write methods take an identifier (for example, `TMessageIdentifier`) or a
234/// primitive. Any or all of the fields in an identifier may be omitted when
235/// writing to the transport. Write methods may even be noops. All of this is
236/// transparent to the caller; as long as a matching `TInputProtocol`
237/// implementation is used, received messages will be decoded correctly.
238///
239/// All methods return a `thrift::Result`. If an `Err` is returned the protocol
240/// instance and its underlying transport should be terminated.
241///
242/// # Examples
243///
244/// Create and use a `TOutputProtocol`
245///
246/// ```no_run
247/// use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType};
248/// use thrift::transport::TTcpChannel;
249///
250/// let mut channel = TTcpChannel::new();
251/// channel.open("127.0.0.1:9090").unwrap();
252///
253/// let mut protocol = TBinaryOutputProtocol::new(channel, true);
254///
255/// protocol.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap();
256/// protocol.write_string("foo").unwrap();
257/// protocol.write_field_end().unwrap();
258/// ```
259pub trait TOutputProtocol {
260    /// Write the beginning of a Thrift message.
261    fn write_message_begin(
262        &mut self,
263        identifier: &TMessageIdentifier,
264    ) -> crate::thrift::Result<usize>;
265    /// Write the end of a Thrift message.
266    fn write_message_end(&mut self) -> crate::thrift::Result<usize>;
267    /// Write the beginning of a Thrift struct.
268    fn write_struct_begin(
269        &mut self,
270        identifier: &TStructIdentifier,
271    ) -> crate::thrift::Result<usize>;
272    /// Write the end of a Thrift struct.
273    fn write_struct_end(&mut self) -> crate::thrift::Result<usize>;
274    /// Write the beginning of a Thrift field.
275    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::thrift::Result<usize>;
276    /// Write the end of a Thrift field.
277    fn write_field_end(&mut self) -> crate::thrift::Result<usize>;
278    /// Write a STOP field indicating that all the fields in a struct have been
279    /// written.
280    fn write_field_stop(&mut self) -> crate::thrift::Result<usize>;
281    /// Write a bool.
282    fn write_bool(&mut self, b: bool) -> crate::thrift::Result<usize>;
283    /// Write a fixed-length byte array.
284    fn write_bytes(&mut self, b: &[u8]) -> crate::thrift::Result<usize>;
285    /// Write an 8-bit signed integer.
286    fn write_i8(&mut self, i: i8) -> crate::thrift::Result<usize>;
287    /// Write a 16-bit signed integer.
288    fn write_i16(&mut self, i: i16) -> crate::thrift::Result<usize>;
289    /// Write a 32-bit signed integer.
290    fn write_i32(&mut self, i: i32) -> crate::thrift::Result<usize>;
291    /// Write a 64-bit signed integer.
292    fn write_i64(&mut self, i: i64) -> crate::thrift::Result<usize>;
293    /// Write a 64-bit float.
294    fn write_double(&mut self, d: f64) -> crate::thrift::Result<usize>;
295    /// Write a fixed-length string.
296    fn write_string(&mut self, s: &str) -> crate::thrift::Result<usize>;
297    /// Write the beginning of a list.
298    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::thrift::Result<usize>;
299    /// Write the end of a list.
300    fn write_list_end(&mut self) -> crate::thrift::Result<usize>;
301    /// Write the beginning of a set.
302    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::thrift::Result<usize>;
303    /// Write the end of a set.
304    fn write_set_end(&mut self) -> crate::thrift::Result<usize>;
305    /// Write the beginning of a map.
306    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::thrift::Result<usize>;
307    /// Write the end of a map.
308    fn write_map_end(&mut self) -> crate::thrift::Result<usize>;
309    /// Flush buffered bytes to the underlying transport.
310    fn flush(&mut self) -> crate::thrift::Result<()>;
311
312    // utility (DO NOT USE IN GENERATED CODE!!!!)
313    //
314
315    /// Write an unsigned byte.
316    ///
317    /// This method should **never** be used in generated code.
318    fn write_byte(&mut self, b: u8) -> crate::thrift::Result<usize>; // FIXME: REMOVE
319}
320
321impl<P> TInputProtocol for Box<P>
322where
323    P: TInputProtocol + ?Sized,
324{
325    fn read_message_begin(&mut self) -> crate::thrift::Result<TMessageIdentifier> {
326        (**self).read_message_begin()
327    }
328
329    fn read_message_end(&mut self) -> crate::thrift::Result<()> {
330        (**self).read_message_end()
331    }
332
333    fn read_struct_begin(&mut self) -> crate::thrift::Result<Option<TStructIdentifier>> {
334        (**self).read_struct_begin()
335    }
336
337    fn read_struct_end(&mut self) -> crate::thrift::Result<()> {
338        (**self).read_struct_end()
339    }
340
341    fn read_field_begin(&mut self) -> crate::thrift::Result<TFieldIdentifier> {
342        (**self).read_field_begin()
343    }
344
345    fn read_field_end(&mut self) -> crate::thrift::Result<()> {
346        (**self).read_field_end()
347    }
348
349    fn read_bool(&mut self) -> crate::thrift::Result<bool> {
350        (**self).read_bool()
351    }
352
353    fn read_bytes(&mut self) -> crate::thrift::Result<Vec<u8>> {
354        (**self).read_bytes()
355    }
356
357    fn read_i8(&mut self) -> crate::thrift::Result<i8> {
358        (**self).read_i8()
359    }
360
361    fn read_i16(&mut self) -> crate::thrift::Result<i16> {
362        (**self).read_i16()
363    }
364
365    fn read_i32(&mut self) -> crate::thrift::Result<i32> {
366        (**self).read_i32()
367    }
368
369    fn read_i64(&mut self) -> crate::thrift::Result<i64> {
370        (**self).read_i64()
371    }
372
373    fn read_double(&mut self) -> crate::thrift::Result<f64> {
374        (**self).read_double()
375    }
376
377    fn read_string(&mut self) -> crate::thrift::Result<String> {
378        (**self).read_string()
379    }
380
381    fn read_list_begin(&mut self) -> crate::thrift::Result<TListIdentifier> {
382        (**self).read_list_begin()
383    }
384
385    fn read_list_end(&mut self) -> crate::thrift::Result<()> {
386        (**self).read_list_end()
387    }
388
389    fn read_set_begin(&mut self) -> crate::thrift::Result<TSetIdentifier> {
390        (**self).read_set_begin()
391    }
392
393    fn read_set_end(&mut self) -> crate::thrift::Result<()> {
394        (**self).read_set_end()
395    }
396
397    fn read_map_begin(&mut self) -> crate::thrift::Result<TMapIdentifier> {
398        (**self).read_map_begin()
399    }
400
401    fn read_map_end(&mut self) -> crate::thrift::Result<()> {
402        (**self).read_map_end()
403    }
404
405    fn read_byte(&mut self) -> crate::thrift::Result<u8> {
406        (**self).read_byte()
407    }
408}
409
410impl<P> TOutputProtocol for Box<P>
411where
412    P: TOutputProtocol + ?Sized,
413{
414    fn write_message_begin(
415        &mut self,
416        identifier: &TMessageIdentifier,
417    ) -> crate::thrift::Result<usize> {
418        (**self).write_message_begin(identifier)
419    }
420
421    fn write_message_end(&mut self) -> crate::thrift::Result<usize> {
422        (**self).write_message_end()
423    }
424
425    fn write_struct_begin(
426        &mut self,
427        identifier: &TStructIdentifier,
428    ) -> crate::thrift::Result<usize> {
429        (**self).write_struct_begin(identifier)
430    }
431
432    fn write_struct_end(&mut self) -> crate::thrift::Result<usize> {
433        (**self).write_struct_end()
434    }
435
436    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::thrift::Result<usize> {
437        (**self).write_field_begin(identifier)
438    }
439
440    fn write_field_end(&mut self) -> crate::thrift::Result<usize> {
441        (**self).write_field_end()
442    }
443
444    fn write_field_stop(&mut self) -> crate::thrift::Result<usize> {
445        (**self).write_field_stop()
446    }
447
448    fn write_bool(&mut self, b: bool) -> crate::thrift::Result<usize> {
449        (**self).write_bool(b)
450    }
451
452    fn write_bytes(&mut self, b: &[u8]) -> crate::thrift::Result<usize> {
453        (**self).write_bytes(b)
454    }
455
456    fn write_i8(&mut self, i: i8) -> crate::thrift::Result<usize> {
457        (**self).write_i8(i)
458    }
459
460    fn write_i16(&mut self, i: i16) -> crate::thrift::Result<usize> {
461        (**self).write_i16(i)
462    }
463
464    fn write_i32(&mut self, i: i32) -> crate::thrift::Result<usize> {
465        (**self).write_i32(i)
466    }
467
468    fn write_i64(&mut self, i: i64) -> crate::thrift::Result<usize> {
469        (**self).write_i64(i)
470    }
471
472    fn write_double(&mut self, d: f64) -> crate::thrift::Result<usize> {
473        (**self).write_double(d)
474    }
475
476    fn write_string(&mut self, s: &str) -> crate::thrift::Result<usize> {
477        (**self).write_string(s)
478    }
479
480    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::thrift::Result<usize> {
481        (**self).write_list_begin(identifier)
482    }
483
484    fn write_list_end(&mut self) -> crate::thrift::Result<usize> {
485        (**self).write_list_end()
486    }
487
488    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::thrift::Result<usize> {
489        (**self).write_set_begin(identifier)
490    }
491
492    fn write_set_end(&mut self) -> crate::thrift::Result<usize> {
493        (**self).write_set_end()
494    }
495
496    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::thrift::Result<usize> {
497        (**self).write_map_begin(identifier)
498    }
499
500    fn write_map_end(&mut self) -> crate::thrift::Result<usize> {
501        (**self).write_map_end()
502    }
503
504    fn flush(&mut self) -> crate::thrift::Result<()> {
505        (**self).flush()
506    }
507
508    fn write_byte(&mut self, b: u8) -> crate::thrift::Result<usize> {
509        (**self).write_byte(b)
510    }
511}
512
513/// Thrift message identifier.
514#[derive(Clone, Debug, Eq, PartialEq)]
515pub struct TMessageIdentifier {
516    /// Service call the message is associated with.
517    pub name: String,
518    /// Message type.
519    pub message_type: TMessageType,
520    /// Ordered sequence number identifying the message.
521    pub sequence_number: i32,
522}
523
524impl TMessageIdentifier {
525    /// Create a `TMessageIdentifier` for a Thrift service-call named `name`
526    /// with message type `message_type` and sequence number `sequence_number`.
527    pub fn new<S: Into<String>>(
528        name: S,
529        message_type: TMessageType,
530        sequence_number: i32,
531    ) -> TMessageIdentifier {
532        TMessageIdentifier {
533            name: name.into(),
534            message_type,
535            sequence_number,
536        }
537    }
538}
539
540/// Thrift struct identifier.
541#[derive(Clone, Debug, Eq, PartialEq)]
542pub struct TStructIdentifier {
543    /// Name of the encoded Thrift struct.
544    pub name: String,
545}
546
547impl TStructIdentifier {
548    /// Create a `TStructIdentifier` for a struct named `name`.
549    pub fn new<S: Into<String>>(name: S) -> TStructIdentifier {
550        TStructIdentifier { name: name.into() }
551    }
552}
553
554/// Thrift field identifier.
555#[derive(Clone, Debug, Eq, PartialEq)]
556pub struct TFieldIdentifier {
557    /// Name of the Thrift field.
558    ///
559    /// `None` if it's not sent over the wire.
560    pub name: Option<String>,
561    /// Field type.
562    ///
563    /// This may be a primitive, container, or a struct.
564    pub field_type: TType,
565    /// Thrift field id.
566    ///
567    /// `None` only if `field_type` is `TType::Stop`.
568    pub id: Option<i16>,
569}
570
571impl TFieldIdentifier {
572    /// Create a `TFieldIdentifier` for a field named `name` with type
573    /// `field_type` and field id `id`.
574    ///
575    /// `id` should be `None` if `field_type` is `TType::Stop`.
576    pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier
577    where
578        N: Into<Option<S>>,
579        S: Into<String>,
580        I: Into<Option<i16>>,
581    {
582        TFieldIdentifier {
583            name: name.into().map(|n| n.into()),
584            field_type,
585            id: id.into(),
586        }
587    }
588}
589
590/// Thrift list identifier.
591#[derive(Clone, Debug, Eq, PartialEq)]
592pub struct TListIdentifier {
593    /// Type of the elements in the list.
594    pub element_type: TType,
595    /// Number of elements in the list.
596    pub size: i32,
597}
598
599impl TListIdentifier {
600    /// Create a `TListIdentifier` for a list with `size` elements of type
601    /// `element_type`.
602    pub fn new(element_type: TType, size: i32) -> TListIdentifier {
603        TListIdentifier { element_type, size }
604    }
605}
606
607/// Thrift set identifier.
608#[derive(Clone, Debug, Eq, PartialEq)]
609pub struct TSetIdentifier {
610    /// Type of the elements in the set.
611    pub element_type: TType,
612    /// Number of elements in the set.
613    pub size: i32,
614}
615
616impl TSetIdentifier {
617    /// Create a `TSetIdentifier` for a set with `size` elements of type
618    /// `element_type`.
619    pub fn new(element_type: TType, size: i32) -> TSetIdentifier {
620        TSetIdentifier { element_type, size }
621    }
622}
623
624/// Thrift map identifier.
625#[derive(Clone, Debug, Eq, PartialEq)]
626pub struct TMapIdentifier {
627    /// Map key type.
628    pub key_type: Option<TType>,
629    /// Map value type.
630    pub value_type: Option<TType>,
631    /// Number of entries in the map.
632    pub size: i32,
633}
634
635impl TMapIdentifier {
636    /// Create a `TMapIdentifier` for a map with `size` entries of type
637    /// `key_type -> value_type`.
638    pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier
639    where
640        K: Into<Option<TType>>,
641        V: Into<Option<TType>>,
642    {
643        TMapIdentifier {
644            key_type: key_type.into(),
645            value_type: value_type.into(),
646            size,
647        }
648    }
649}
650
651/// Thrift message types.
652#[derive(Clone, Copy, Debug, Eq, PartialEq)]
653pub enum TMessageType {
654    /// Service-call request.
655    Call,
656    /// Service-call response.
657    Reply,
658    /// Unexpected error in the remote service.
659    Exception,
660    /// One-way service-call request (no response is expected).
661    OneWay,
662}
663
664impl Display for TMessageType {
665    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
666        match *self {
667            TMessageType::Call => write!(f, "Call"),
668            TMessageType::Reply => write!(f, "Reply"),
669            TMessageType::Exception => write!(f, "Exception"),
670            TMessageType::OneWay => write!(f, "OneWay"),
671        }
672    }
673}
674
675impl From<TMessageType> for u8 {
676    fn from(message_type: TMessageType) -> Self {
677        match message_type {
678            TMessageType::Call => 0x01,
679            TMessageType::Reply => 0x02,
680            TMessageType::Exception => 0x03,
681            TMessageType::OneWay => 0x04,
682        }
683    }
684}
685
686impl TryFrom<u8> for TMessageType {
687    type Error = Error;
688    fn try_from(b: u8) -> Result<Self, Self::Error> {
689        match b {
690            0x01 => Ok(TMessageType::Call),
691            0x02 => Ok(TMessageType::Reply),
692            0x03 => Ok(TMessageType::Exception),
693            0x04 => Ok(TMessageType::OneWay),
694            unkn => Err(Error::Protocol(ProtocolError {
695                kind: ProtocolErrorKind::InvalidData,
696                message: format!("cannot convert {} to TMessageType", unkn),
697            })),
698        }
699    }
700}
701
702/// Thrift struct-field types.
703#[derive(Clone, Copy, Debug, Eq, PartialEq)]
704pub enum TType {
705    /// Indicates that there are no more serialized fields in this Thrift struct.
706    Stop,
707    /// Void (`()`) field.
708    Void,
709    /// Boolean.
710    Bool,
711    /// Signed 8-bit int.
712    I08,
713    /// Double-precision number.
714    Double,
715    /// Signed 16-bit int.
716    I16,
717    /// Signed 32-bit int.
718    I32,
719    /// Signed 64-bit int.
720    I64,
721    /// UTF-8 string.
722    String,
723    /// UTF-7 string. *Unsupported*.
724    Utf7,
725    /// Thrift struct.
726    Struct,
727    /// Map.
728    Map,
729    /// Set.
730    Set,
731    /// List.
732    List,
733    /// UTF-8 string.
734    Utf8,
735    /// UTF-16 string. *Unsupported*.
736    Utf16,
737}
738
739impl Display for TType {
740    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
741        match *self {
742            TType::Stop => write!(f, "STOP"),
743            TType::Void => write!(f, "void"),
744            TType::Bool => write!(f, "bool"),
745            TType::I08 => write!(f, "i08"),
746            TType::Double => write!(f, "double"),
747            TType::I16 => write!(f, "i16"),
748            TType::I32 => write!(f, "i32"),
749            TType::I64 => write!(f, "i64"),
750            TType::String => write!(f, "string"),
751            TType::Utf7 => write!(f, "UTF7"),
752            TType::Struct => write!(f, "struct"),
753            TType::Map => write!(f, "map"),
754            TType::Set => write!(f, "set"),
755            TType::List => write!(f, "list"),
756            TType::Utf8 => write!(f, "UTF8"),
757            TType::Utf16 => write!(f, "UTF16"),
758        }
759    }
760}
761
762/// Compare the expected message sequence number `expected` with the received
763/// message sequence number `actual`.
764///
765/// Return `()` if `actual == expected`, `Err` otherwise.
766pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> crate::thrift::Result<()> {
767    if expected == actual {
768        Ok(())
769    } else {
770        Err(crate::thrift::Error::Application(
771            crate::thrift::ApplicationError {
772                kind: crate::thrift::ApplicationErrorKind::BadSequenceId,
773                message: format!("expected {} got {}", expected, actual),
774            },
775        ))
776    }
777}
778
779/// Compare the expected service-call name `expected` with the received
780/// service-call name `actual`.
781///
782/// Return `()` if `actual == expected`, `Err` otherwise.
783pub fn verify_expected_service_call(expected: &str, actual: &str) -> crate::thrift::Result<()> {
784    if expected == actual {
785        Ok(())
786    } else {
787        Err(crate::thrift::Error::Application(ApplicationError {
788            kind: crate::thrift::ApplicationErrorKind::WrongMethodName,
789            message: format!("expected {} got {}", expected, actual),
790        }))
791    }
792}
793
794/// Compare the expected message type `expected` with the received message type
795/// `actual`.
796///
797/// Return `()` if `actual == expected`, `Err` otherwise.
798pub fn verify_expected_message_type(
799    expected: TMessageType,
800    actual: TMessageType,
801) -> crate::thrift::Result<()> {
802    if expected == actual {
803        Ok(())
804    } else {
805        Err(crate::thrift::Error::Application(ApplicationError {
806            kind: crate::thrift::ApplicationErrorKind::InvalidMessageType,
807            message: format!("expected {} got {}", expected, actual),
808        }))
809    }
810}
811
812/// Check if a required Thrift struct field exists.
813///
814/// Return `()` if it does, `Err` otherwise.
815pub fn verify_required_field_exists<T>(
816    field_name: &str,
817    field: &Option<T>,
818) -> crate::thrift::Result<()> {
819    match *field {
820        Some(_) => Ok(()),
821        None => Err(Error::Protocol(ProtocolError {
822            kind: ProtocolErrorKind::Unknown,
823            message: format!("missing required field {}", field_name),
824        })),
825    }
826}
827
828/// Extract the field id from a Thrift field identifier.
829///
830/// `field_ident` must *not* have `TFieldIdentifier.field_type` of type `TType::Stop`.
831///
832/// Return `TFieldIdentifier.id` if an id exists, `Err` otherwise.
833pub fn field_id(field_ident: &TFieldIdentifier) -> crate::thrift::Result<i16> {
834    field_ident.id.ok_or_else(|| {
835        crate::thrift::Error::Protocol(crate::thrift::ProtocolError {
836            kind: crate::thrift::ProtocolErrorKind::Unknown,
837            message: format!("missing field in in {:?}", field_ident),
838        })
839    })
840}