compact_thrift_runtime/
lib.rs

1mod error;
2pub mod macros;
3mod protocol;
4mod types;
5mod uleb;
6
7pub use error::*;
8pub use protocol::*;
9
10#[cfg(test)]
11mod tests {
12    use crate::{CompactThriftInput, CompactThriftOutput, CompactThriftProtocol, FieldName, skip_field, CompactThriftInputSlice, ThriftError};
13    use crate::uleb::decode_uleb;
14
15    #[test]
16    fn test_size_of_error() {
17        assert_eq!(std::mem::size_of::<ThriftError>(), 16);
18        assert_eq!(std::mem::size_of::<Result<(), ThriftError>>(), 16);
19    }
20
21    #[test]
22    fn test_field_name() {
23        assert_eq!(std::mem::size_of::<FieldName>(), std::mem::size_of::<usize>());
24        assert_eq!(&FieldName::from(c"foobar").to_string(), "foobar");
25    }
26
27    #[test]
28    fn test_slice_input_read_byte() {
29        let mut input = CompactThriftInputSlice::new(&[1]);
30        assert_eq!(input.read_byte().unwrap(), 1);
31    }
32
33    #[test]
34    fn test_read_uleb() {
35        assert_eq!(decode_uleb(&mut CompactThriftInputSlice::new(&[1])).unwrap(), 1);
36        assert_eq!(decode_uleb(&mut CompactThriftInputSlice::new(&[0b0111_1111])).unwrap(), 0b0111_1111);
37        assert_eq!(decode_uleb(&mut CompactThriftInputSlice::new(&[0b1000_1111, 0b0111_0101])).unwrap(), 0b0011_1010_1000_1111);
38    }
39
40    #[test]
41    fn test_read_uleb_overlong() {
42        decode_uleb(&mut CompactThriftInputSlice::new(&[0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0b1000_0001, 0])).unwrap();
43    }
44
45    #[test]
46    #[cfg(target_feature = "sse2")]
47    fn test_skip_uleb_sse2() {
48        use crate::uleb::skip_uleb_sse2;
49        {
50            let buf = &[0; 16];
51            assert_eq!(unsafe { skip_uleb_sse2(buf) }, &buf[1..]);
52        }
53        {
54            let buf = &mut [0; 16];
55            buf[1] = 0x81;
56            assert_eq!(unsafe { skip_uleb_sse2(buf) }, &buf[1..]);
57        }
58        {
59            let buf = &mut [0; 16];
60            buf[0] = 0x80;
61            buf[1] = 0x01;
62            assert_eq!(unsafe { skip_uleb_sse2(buf) }, &buf[2..]);
63        }
64    }
65
66    #[test]
67    fn test_slice_input_read_i32() {
68        assert_eq!(CompactThriftInputSlice::new(&[0]).read_i32().unwrap(), 0);
69        assert_eq!(CompactThriftInputSlice::new(&[1]).read_i32().unwrap(), -1);
70        assert_eq!(CompactThriftInputSlice::new(&[2]).read_i32().unwrap(), 1);
71
72        assert_eq!(CompactThriftInputSlice::new(&[0b0111_1111]).read_i32().unwrap(), -64);
73        assert_eq!(CompactThriftInputSlice::new(&[0b1000_1111, 0b0111_0101]).read_i32().unwrap(), -7496);
74        assert_eq!(CompactThriftInputSlice::new(&[0b1000_1111, 0b0111_0101, 0, 0]).read_i32().unwrap(), -7496);
75        assert_eq!(CompactThriftInputSlice::new(&[0b1000_1111, 0b0111_0101, 0, 0, 0]).read_i32().unwrap(), -7496);
76    }
77
78    #[test]
79    fn test_uleb_roundtrip() {
80        let mut w = vec![];
81        w.write_i64(1234567890).unwrap();
82        let mut r = CompactThriftInputSlice::new(&w);
83        assert_eq!(r.read_i64().unwrap(), 1234567890);
84    }
85
86    #[test]
87    fn test_read_vec_bool() {
88        let mut data = CompactThriftInputSlice::new(&[0x42, 0, 1, 1, 0]);
89        let actual = Vec::<bool>::read_thrift(&mut data).unwrap();
90        let expected = vec![false, true, true, false];
91        assert_eq!(&actual, &expected);
92
93        // also allow element type 1 for boolean
94        let mut data = CompactThriftInputSlice::new(&[0x41, 0, 1, 1, 0]);
95        let actual = Vec::<bool>::read_thrift(&mut data).unwrap();
96        let expected = vec![false, true, true, false];
97        assert_eq!(&actual, &expected);
98    }
99
100    #[test]
101    fn test_read_box() {
102        let mut data = CompactThriftInputSlice::new(&[0x2]);
103        let actual = Box::<i32>::read_thrift(&mut data).unwrap();
104        let expected = Box::new(1);
105        assert_eq!(&actual, &expected);
106    }
107
108    #[test]
109    fn test_read_option_box() {
110        let mut data = CompactThriftInputSlice::new(&[0x2]);
111        let actual = Option::<Box::<i32>>::read_thrift(&mut data).unwrap();
112        let expected = Some(Box::new(1));
113        assert_eq!(&actual, &expected);
114    }
115
116    #[test]
117    fn test_empty_vec_roundtrip() {
118        let input = Vec::<i64>::default();
119        let mut buffer = vec![];
120        input.write_thrift(&mut buffer).unwrap();
121        let result = Vec::<i64>::read_thrift(&mut CompactThriftInputSlice::new(&buffer)).unwrap();
122        assert_eq!(&result, &input);
123    }
124
125    #[test]
126    fn test_vec_bool_roundtrip() {
127        let input = vec![true, false, false, true];
128        let mut buffer = vec![];
129        input.write_thrift(&mut buffer).unwrap();
130        let result = Vec::<bool>::read_thrift(&mut CompactThriftInputSlice::new(&buffer)).unwrap();
131        assert_eq!(&result, &input);
132    }
133
134    #[test]
135    fn test_vec_integer_roundtrip() {
136        let input = vec![1_i64, i64::MIN, i64::MAX, 9999999];
137        let mut buffer = vec![];
138        input.write_thrift(&mut buffer).unwrap();
139        let result = Vec::<i64>::read_thrift(&mut CompactThriftInputSlice::new(&buffer)).unwrap();
140        assert_eq!(&result, &input);
141    }
142
143    #[test]
144    fn test_skip_vec_bool() {
145        let input = vec![true, false, false, true];
146        let mut buffer = vec![];
147        input.write_thrift(&mut buffer).unwrap();
148        let mut slice = CompactThriftInputSlice::new(&buffer);
149        skip_field(&mut slice, Vec::<bool>::FIELD_TYPE, true).unwrap();
150        assert_eq!(&slice.as_slice(), &[]);
151    }
152
153    #[test]
154    fn test_skip_vec_integer() {
155        let input = vec![1_i64, 999999999999, -1, i64::MAX];
156        let mut buffer = vec![];
157        input.write_thrift(&mut buffer).unwrap();
158        let mut slice = CompactThriftInputSlice::new(&buffer);
159        skip_field(&mut slice, Vec::<i64>::FIELD_TYPE, true).unwrap();
160        assert_eq!(&slice.as_slice(), &[]);
161    }
162}