matrix_pickle/
lib.rs

1// Copyright 2021, 2022 Damir Jelić
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#![doc = include_str!("../README.md")]
16#![deny(
17    clippy::mem_forget,
18    clippy::unwrap_used,
19    dead_code,
20    missing_docs,
21    trivial_casts,
22    trivial_numeric_casts,
23    unsafe_code,
24    unsafe_op_in_unsafe_fn,
25    unused_import_braces,
26    unused_qualifications
27)]
28#![cfg_attr(docsrs, feature(doc_auto_cfg))]
29
30extern crate self as matrix_pickle;
31
32mod decode;
33mod encode;
34mod error;
35
36const MAX_ARRAY_LENGTH: usize = u16::MAX as usize;
37
38#[cfg(feature = "derive")]
39pub use matrix_pickle_derive::*;
40
41pub use decode::*;
42pub use encode::*;
43pub use error::*;
44
45#[cfg(test)]
46mod test {
47    use proptest::prelude::*;
48
49    use super::*;
50
51    macro_rules! encode_cycle {
52        ($value:expr => $type:ty) => {
53            let value = $value;
54
55            let encoded = value
56                .encode_to_vec()
57                .expect("We can always encode into to a Vec");
58            let decoded = <$type>::decode_from_slice(&encoded)
59                .expect("Decoding a freshly encoded value always works");
60
61            assert_eq!(
62                value, decoded,
63                "The original value and the decoded value are not the same"
64            );
65        };
66    }
67
68    macro_rules! encode_length_check {
69        ($value:expr) => {
70            let mut buffer = Vec::new();
71            let size = $value
72                .encode(&mut buffer)
73                .expect("We can always encode into to a Vec");
74            assert_eq!(size, buffer.len());
75        };
76    }
77
78    #[test]
79    fn encode_cycle() {
80        encode_cycle!(10u8 => u8);
81        encode_cycle!(10u32 => u32);
82        encode_cycle!(10usize => usize);
83        encode_cycle!(true => bool);
84        encode_cycle!(false => bool);
85        encode_cycle!(vec![1, 2, 3, 4] => Vec<u8>);
86    }
87
88    #[test]
89    fn encode_length_check() {
90        encode_length_check!(10u8);
91        encode_length_check!(10u32);
92        encode_length_check!(10usize);
93        encode_length_check!(true);
94        encode_length_check!(false);
95        encode_length_check!([1u32, 2u32, 3u32, 4u32]);
96    }
97
98    proptest! {
99        #[test]
100        fn encode_cycle_u8(a in 0..u8::MAX) {
101            encode_cycle!(a => u8);
102        }
103
104        #[test]
105        fn encode_cycle_u32(a in 0..u32::MAX) {
106            encode_cycle!(a => u32);
107        }
108
109        #[test]
110        fn encode_cycle_usize(a in 0..u32::MAX) {
111            let a = a as usize;
112            encode_cycle!(a => usize);
113        }
114
115        fn encode_cycle_vec(bytes in prop::collection::vec(any::<u8>(), 0..1000)) {
116            encode_cycle!(bytes => Vec<u8>);
117        }
118    }
119
120    #[test]
121    fn max_array_length() {
122        assert!(matches!(
123            [false; MAX_ARRAY_LENGTH + 1].encode_to_vec(),
124            Err(EncodeError::ArrayTooBig(_))
125        ));
126
127        let mut buffer = Vec::<u8>::new();
128        (MAX_ARRAY_LENGTH + 1)
129            .encode(&mut buffer)
130            .expect("Should encode length");
131        assert!(matches!(
132            Vec::<bool>::decode(&mut &*buffer),
133            Err(DecodeError::ArrayTooBig(_))
134        ));
135    }
136
137    #[test]
138    #[cfg(feature = "derive")]
139    fn derive() {
140        #[derive(Clone, Encode, Decode, PartialEq, Debug)]
141        struct Foo {
142            thing: [u8; 32],
143            #[secret]
144            another: Box<[u8; 64]>,
145        }
146
147        let foo = Foo {
148            thing: [1u8; 32],
149            another: Box::new([2u8; 64]),
150        };
151
152        encode_cycle!(foo.clone() => Foo);
153
154        #[derive(Clone, Encode, Decode, PartialEq, Debug)]
155        struct Bar([u8; 32]);
156
157        let bar = Bar([1u8; 32]);
158        encode_cycle!(bar.clone() => Bar);
159
160        #[derive(Encode, Decode, PartialEq, Debug)]
161        enum Something {
162            Foo(Foo),
163            Bar(Bar),
164        }
165
166        let something = Something::Foo(foo);
167        encode_cycle!(something => Something);
168
169        let something = Something::Bar(bar);
170        encode_cycle!(something => Something);
171    }
172}