1use std::convert::{From, TryFrom};
61use std::fmt;
62use std::fmt::{Display, Formatter};
63
64use crate::transport::{TReadTransport, TWriteTransport};
65use crate::{ProtocolError, ProtocolErrorKind, TConfiguration};
66
67#[cfg(test)]
68macro_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#[cfg(test)]
76macro_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)]
83macro_rules! set_readable_bytes {
84 ($i_prot:ident, $bytes:expr) => {
85 $i_prot.transport.set_readable_bytes($bytes);
86 };
87}
88
89mod binary;
90mod compact;
91mod multiplexed;
92mod stored;
93
94pub use self::binary::{
95 TBinaryInputProtocol, TBinaryInputProtocolFactory, TBinaryOutputProtocol,
96 TBinaryOutputProtocolFactory,
97};
98pub use self::compact::{
99 TCompactInputProtocol, TCompactInputProtocolFactory, TCompactOutputProtocol,
100 TCompactOutputProtocolFactory,
101};
102pub use self::multiplexed::TMultiplexedOutputProtocol;
103pub use self::stored::TStoredInputProtocol;
104
105pub 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
113const MAXIMUM_SKIP_DEPTH: i8 = 64;
118
119pub trait TInputProtocol {
148 fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier>;
150 fn read_message_end(&mut self) -> crate::Result<()>;
152 fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>>;
154 fn read_struct_end(&mut self) -> crate::Result<()>;
156 fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier>;
158 fn read_field_end(&mut self) -> crate::Result<()>;
160 fn read_bool(&mut self) -> crate::Result<bool>;
162 fn read_bytes(&mut self) -> crate::Result<Vec<u8>>;
164 fn read_i8(&mut self) -> crate::Result<i8>;
166 fn read_i16(&mut self) -> crate::Result<i16>;
168 fn read_i32(&mut self) -> crate::Result<i32>;
170 fn read_i64(&mut self) -> crate::Result<i64>;
172 fn read_double(&mut self) -> crate::Result<f64>;
174 fn read_uuid(&mut self) -> crate::Result<uuid::Uuid>;
176 fn read_string(&mut self) -> crate::Result<String>;
178 fn read_list_begin(&mut self) -> crate::Result<TListIdentifier>;
180 fn read_list_end(&mut self) -> crate::Result<()>;
182 fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier>;
184 fn read_set_end(&mut self) -> crate::Result<()>;
186 fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier>;
188 fn read_map_end(&mut self) -> crate::Result<()>;
190 fn skip(&mut self, field_type: TType) -> crate::Result<()> {
193 self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH)
194 }
195 fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> {
197 if depth == 0 {
198 return Err(crate::Error::Protocol(ProtocolError {
199 kind: ProtocolErrorKind::DepthLimit,
200 message: format!("cannot parse past {:?}", field_type),
201 }));
202 }
203
204 match field_type {
205 TType::Bool => self.read_bool().map(|_| ()),
206 TType::I08 => self.read_i8().map(|_| ()),
207 TType::I16 => self.read_i16().map(|_| ()),
208 TType::I32 => self.read_i32().map(|_| ()),
209 TType::I64 => self.read_i64().map(|_| ()),
210 TType::Double => self.read_double().map(|_| ()),
211 TType::String => self.read_bytes().map(|_| ()),
212 TType::Uuid => self.read_uuid().map(|_| ()),
213 TType::Struct => {
214 self.read_struct_begin()?;
215 loop {
216 let field_ident = self.read_field_begin()?;
217 if field_ident.field_type == TType::Stop {
218 break;
219 }
220 self.skip_till_depth(field_ident.field_type, depth - 1)?;
221 }
222 self.read_struct_end()
223 }
224 TType::List => {
225 let list_ident = self.read_list_begin()?;
226 for _ in 0..list_ident.size {
227 self.skip_till_depth(list_ident.element_type, depth - 1)?;
228 }
229 self.read_list_end()
230 }
231 TType::Set => {
232 let set_ident = self.read_set_begin()?;
233 for _ in 0..set_ident.size {
234 self.skip_till_depth(set_ident.element_type, depth - 1)?;
235 }
236 self.read_set_end()
237 }
238 TType::Map => {
239 let map_ident = self.read_map_begin()?;
240 for _ in 0..map_ident.size {
241 let key_type = map_ident
242 .key_type
243 .expect("non-zero sized map should contain key type");
244 let val_type = map_ident
245 .value_type
246 .expect("non-zero sized map should contain value type");
247 self.skip_till_depth(key_type, depth - 1)?;
248 self.skip_till_depth(val_type, depth - 1)?;
249 }
250 self.read_map_end()
251 }
252 u => Err(crate::Error::Protocol(ProtocolError {
253 kind: ProtocolErrorKind::Unknown,
254 message: format!("cannot skip field type {:?}", &u),
255 })),
256 }
257 }
258
259 fn read_byte(&mut self) -> crate::Result<u8>;
266
267 fn min_serialized_size(&self, field_type: TType) -> usize {
273 self::compact::compact_protocol_min_serialized_size(field_type)
274 }
275}
276
277pub trait TOutputProtocol {
309 fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()>;
311 fn write_message_end(&mut self) -> crate::Result<()>;
313 fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()>;
315 fn write_struct_end(&mut self) -> crate::Result<()>;
317 fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()>;
319 fn write_field_end(&mut self) -> crate::Result<()>;
321 fn write_field_stop(&mut self) -> crate::Result<()>;
324 fn write_bool(&mut self, b: bool) -> crate::Result<()>;
326 fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()>;
328 fn write_i8(&mut self, i: i8) -> crate::Result<()>;
330 fn write_i16(&mut self, i: i16) -> crate::Result<()>;
332 fn write_i32(&mut self, i: i32) -> crate::Result<()>;
334 fn write_i64(&mut self, i: i64) -> crate::Result<()>;
336 fn write_double(&mut self, d: f64) -> crate::Result<()>;
338 fn write_uuid(&mut self, uuid: &uuid::Uuid) -> crate::Result<()>;
340 fn write_string(&mut self, s: &str) -> crate::Result<()>;
342 fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()>;
344 fn write_list_end(&mut self) -> crate::Result<()>;
346 fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()>;
348 fn write_set_end(&mut self) -> crate::Result<()>;
350 fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()>;
352 fn write_map_end(&mut self) -> crate::Result<()>;
354 fn flush(&mut self) -> crate::Result<()>;
356
357 fn write_byte(&mut self, b: u8) -> crate::Result<()>; }
365
366impl<P> TInputProtocol for Box<P>
367where
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
463impl<P> TOutputProtocol for Box<P>
464where
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
564pub trait TInputProtocolFactory {
582 fn create(&self, transport: Box<dyn TReadTransport + Send>) -> Box<dyn TInputProtocol + Send>;
584}
585
586impl<T> TInputProtocolFactory for Box<T>
587where
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
595pub trait TOutputProtocolFactory {
613 fn create(&self, transport: Box<dyn TWriteTransport + Send>)
615 -> Box<dyn TOutputProtocol + Send>;
616}
617
618impl<T> TOutputProtocolFactory for Box<T>
619where
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#[derive(Clone, Debug, Eq, PartialEq)]
632pub struct TMessageIdentifier {
633 pub name: String,
635 pub message_type: TMessageType,
637 pub sequence_number: i32,
639}
640
641impl TMessageIdentifier {
642 pub fn new<S: Into<String>>(
645 name: S,
646 message_type: TMessageType,
647 sequence_number: i32,
648 ) -> TMessageIdentifier {
649 TMessageIdentifier {
650 name: name.into(),
651 message_type,
652 sequence_number,
653 }
654 }
655}
656
657#[derive(Clone, Debug, Eq, PartialEq)]
659pub struct TStructIdentifier {
660 pub name: String,
662}
663
664impl TStructIdentifier {
665 pub fn new<S: Into<String>>(name: S) -> TStructIdentifier {
667 TStructIdentifier { name: name.into() }
668 }
669}
670
671#[derive(Clone, Debug, Eq, PartialEq)]
673pub struct TFieldIdentifier {
674 pub name: Option<String>,
678 pub field_type: TType,
682 pub id: Option<i16>,
686}
687
688impl TFieldIdentifier {
689 pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier
694 where
695 N: Into<Option<S>>,
696 S: Into<String>,
697 I: Into<Option<i16>>,
698 {
699 TFieldIdentifier {
700 name: name.into().map(|n| n.into()),
701 field_type,
702 id: id.into(),
703 }
704 }
705}
706
707#[derive(Clone, Debug, Eq, PartialEq)]
709pub struct TListIdentifier {
710 pub element_type: TType,
712 pub size: i32,
714}
715
716impl TListIdentifier {
717 pub fn new(element_type: TType, size: i32) -> TListIdentifier {
720 TListIdentifier { element_type, size }
721 }
722}
723
724#[derive(Clone, Debug, Eq, PartialEq)]
726pub struct TSetIdentifier {
727 pub element_type: TType,
729 pub size: i32,
731}
732
733impl TSetIdentifier {
734 pub fn new(element_type: TType, size: i32) -> TSetIdentifier {
737 TSetIdentifier { element_type, size }
738 }
739}
740
741#[derive(Clone, Debug, Eq, PartialEq)]
743pub struct TMapIdentifier {
744 pub key_type: Option<TType>,
746 pub value_type: Option<TType>,
748 pub size: i32,
750}
751
752impl TMapIdentifier {
753 pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier
756 where
757 K: Into<Option<TType>>,
758 V: Into<Option<TType>>,
759 {
760 TMapIdentifier {
761 key_type: key_type.into(),
762 value_type: value_type.into(),
763 size,
764 }
765 }
766}
767
768#[derive(Clone, Copy, Debug, Eq, PartialEq)]
770pub enum TMessageType {
771 Call,
773 Reply,
775 Exception,
777 OneWay,
779}
780
781impl Display for TMessageType {
782 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
783 match *self {
784 TMessageType::Call => write!(f, "Call"),
785 TMessageType::Reply => write!(f, "Reply"),
786 TMessageType::Exception => write!(f, "Exception"),
787 TMessageType::OneWay => write!(f, "OneWay"),
788 }
789 }
790}
791
792impl From<TMessageType> for u8 {
793 fn from(message_type: TMessageType) -> Self {
794 match message_type {
795 TMessageType::Call => 0x01,
796 TMessageType::Reply => 0x02,
797 TMessageType::Exception => 0x03,
798 TMessageType::OneWay => 0x04,
799 }
800 }
801}
802
803impl TryFrom<u8> for TMessageType {
804 type Error = crate::Error;
805 fn try_from(b: u8) -> Result<Self, Self::Error> {
806 match b {
807 0x01 => Ok(TMessageType::Call),
808 0x02 => Ok(TMessageType::Reply),
809 0x03 => Ok(TMessageType::Exception),
810 0x04 => Ok(TMessageType::OneWay),
811 unkn => Err(crate::Error::Protocol(ProtocolError {
812 kind: ProtocolErrorKind::InvalidData,
813 message: format!("cannot convert {} to TMessageType", unkn),
814 })),
815 }
816 }
817}
818
819#[derive(Clone, Copy, Debug, Eq, PartialEq)]
821pub enum TType {
822 Stop,
824 Void,
826 Bool,
828 I08,
830 Double,
832 I16,
834 I32,
836 I64,
838 String,
840 Utf7,
842 Struct,
844 Map,
846 Set,
848 List,
850 Uuid,
852}
853
854impl Display for TType {
855 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
856 match *self {
857 TType::Stop => write!(f, "STOP"),
858 TType::Void => write!(f, "void"),
859 TType::Bool => write!(f, "bool"),
860 TType::I08 => write!(f, "i08"),
861 TType::Double => write!(f, "double"),
862 TType::I16 => write!(f, "i16"),
863 TType::I32 => write!(f, "i32"),
864 TType::I64 => write!(f, "i64"),
865 TType::String => write!(f, "string"),
866 TType::Utf7 => write!(f, "UTF7"),
867 TType::Struct => write!(f, "struct"),
868 TType::Map => write!(f, "map"),
869 TType::Set => write!(f, "set"),
870 TType::List => write!(f, "list"),
871 TType::Uuid => write!(f, "UUID"),
872 }
873 }
874}
875
876pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> crate::Result<()> {
881 if expected == actual {
882 Ok(())
883 } else {
884 Err(crate::Error::Application(crate::ApplicationError {
885 kind: crate::ApplicationErrorKind::BadSequenceId,
886 message: format!("expected {} got {}", expected, actual),
887 }))
888 }
889}
890
891pub fn verify_expected_service_call(expected: &str, actual: &str) -> crate::Result<()> {
896 if expected == actual {
897 Ok(())
898 } else {
899 Err(crate::Error::Application(crate::ApplicationError {
900 kind: crate::ApplicationErrorKind::WrongMethodName,
901 message: format!("expected {} got {}", expected, actual),
902 }))
903 }
904}
905
906pub fn verify_expected_message_type(
911 expected: TMessageType,
912 actual: TMessageType,
913) -> crate::Result<()> {
914 if expected == actual {
915 Ok(())
916 } else {
917 Err(crate::Error::Application(crate::ApplicationError {
918 kind: crate::ApplicationErrorKind::InvalidMessageType,
919 message: format!("expected {} got {}", expected, actual),
920 }))
921 }
922}
923
924pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> {
928 match *field {
929 Some(_) => Ok(()),
930 None => Err(crate::Error::Protocol(crate::ProtocolError {
931 kind: crate::ProtocolErrorKind::Unknown,
932 message: format!("missing required field {}", field_name),
933 })),
934 }
935}
936
937pub(crate) fn check_container_size(
945 config: &TConfiguration,
946 container_size: i32,
947 element_size: usize,
948) -> crate::Result<()> {
949 if container_size < 0 {
951 return Err(crate::Error::Protocol(ProtocolError::new(
952 ProtocolErrorKind::NegativeSize,
953 format!("Negative container size: {}", container_size),
954 )));
955 }
956
957 let size_as_usize = container_size as usize;
958
959 if let Some(max_size) = config.max_container_size() {
961 if size_as_usize > max_size {
962 return Err(crate::Error::Protocol(ProtocolError::new(
963 ProtocolErrorKind::SizeLimit,
964 format!(
965 "Container size {} exceeds maximum allowed size of {}",
966 container_size, max_size
967 ),
968 )));
969 }
970 }
971
972 if let Some(min_bytes_needed) = size_as_usize.checked_mul(element_size) {
974 if let Some(max_message_size) = config.max_message_size() {
978 if min_bytes_needed > max_message_size {
979 return Err(crate::Error::Protocol(ProtocolError::new(
980 ProtocolErrorKind::SizeLimit,
981 format!(
982 "Container would require {} bytes, exceeding message size limit of {}",
983 min_bytes_needed, max_message_size
984 ),
985 )));
986 }
987 }
988 Ok(())
989 } else {
990 Err(crate::Error::Protocol(ProtocolError::new(
991 ProtocolErrorKind::SizeLimit,
992 format!(
993 "Container size {} with element size {} bytes would result in overflow",
994 container_size, element_size
995 ),
996 )))
997 }
998}
999
1000pub fn field_id(field_ident: &TFieldIdentifier) -> crate::Result<i16> {
1006 field_ident.id.ok_or_else(|| {
1007 crate::Error::Protocol(crate::ProtocolError {
1008 kind: crate::ProtocolErrorKind::Unknown,
1009 message: format!("missing field id in {:?}", field_ident),
1010 })
1011 })
1012}
1013
1014#[cfg(test)]
1015mod 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
1064 fn build_struct_with_unknown_binary_field(payload: &[u8]) -> Vec<u8> {
1067 let mut buf = Vec::new();
1068 buf.push(0x0A); buf.extend_from_slice(&1_i16.to_be_bytes());
1070 buf.extend_from_slice(&42_i64.to_be_bytes());
1071 buf.push(0x0B); buf.extend_from_slice(&99_i16.to_be_bytes());
1073 buf.extend_from_slice(&(payload.len() as i32).to_be_bytes());
1074 buf.extend_from_slice(payload);
1075 buf.push(0x00); buf
1077 }
1078
1079 fn read_struct_skipping_unknown(data: &[u8]) -> crate::Result<i64> {
1080 let cursor = Cursor::new(data.to_vec());
1081 let mut proto = TBinaryInputProtocol::new(cursor, true);
1082 proto.read_struct_begin()?;
1083 let mut known_value: Option<i64> = None;
1084 loop {
1085 let field = proto.read_field_begin()?;
1086 if field.field_type == TType::Stop {
1087 break;
1088 }
1089 match field.id {
1090 Some(1) if field.field_type == TType::I64 => {
1091 known_value = Some(proto.read_i64()?);
1092 }
1093 _ => {
1094 proto.skip(field.field_type)?;
1095 }
1096 }
1097 proto.read_field_end()?;
1098 }
1099 proto.read_struct_end()?;
1100 known_value.ok_or_else(|| {
1101 crate::Error::Protocol(crate::ProtocolError {
1102 kind: crate::ProtocolErrorKind::InvalidData,
1103 message: "missing known field".to_string(),
1104 })
1105 })
1106 }
1107
1108 #[test]
1109 fn must_skip_binary_field_with_non_utf8_bytes() {
1110 let non_utf8: Vec<u8> = vec![
1111 0x04, 0xFF, 0xFE, 0x80, 0x90, 0xAB, 0xCD, 0xEF,
1112 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE,
1113 ];
1114 assert!(String::from_utf8(non_utf8.clone()).is_err());
1115 let data = build_struct_with_unknown_binary_field(&non_utf8);
1116 let result = read_struct_skipping_unknown(&data);
1117 assert!(result.is_ok(), "skip() failed on non-UTF-8 binary: {:?}", result.err());
1118 assert_eq!(result.unwrap(), 42);
1119 }
1120
1121 #[test]
1122 fn must_skip_valid_utf8_string_field() {
1123 let data = build_struct_with_unknown_binary_field(b"hello world");
1124 assert_eq!(read_struct_skipping_unknown(&data).unwrap(), 42);
1125 }
1126
1127 #[test]
1128 fn must_skip_empty_binary_field() {
1129 let data = build_struct_with_unknown_binary_field(&[]);
1130 assert_eq!(read_struct_skipping_unknown(&data).unwrap(), 42);
1131 }
1132}