1#![forbid(unsafe_code)]
2#![deny(missing_docs, unstable_features)]
3#[cfg(all(feature = "futures", feature = "tokio"))]
73compile_error!("Features `futures` and `tokio` are mutually exclusive");
74
75#[cfg(not(any(feature = "futures", feature = "tokio")))]
76compile_error!("Either feature `futures` or `tokio` must be enabled for this crate");
77
78mod config;
79mod decode;
80mod encode;
81mod error;
82
83pub mod io;
84
85#[cfg(feature = "derive")]
86pub use nimble_derive::{Decode, Encode};
87
88pub use async_trait::async_trait;
90
91pub use self::{
92 config::{Config, Endianness},
93 decode::Decode,
94 encode::Encode,
95 error::{Error, Result},
96};
97
98use self::io::{Read, Write};
99
100const DEFAULT_CONFIG: Config = Config::new_default();
101
102pub fn config<'a>() -> &'a Config {
104 &DEFAULT_CONFIG
105}
106
107#[inline]
109pub async fn encode<E: Encode + ?Sized>(value: &E) -> Vec<u8> {
110 DEFAULT_CONFIG.encode(value).await
111}
112
113#[inline]
115pub async fn encode_to<E: Encode + ?Sized, W: Write + Unpin + Send>(
116 value: &E,
117 writer: W,
118) -> Result<usize> {
119 DEFAULT_CONFIG.encode_to(value, writer).await
120}
121
122#[inline]
124pub async fn decode<D: Decode, T: AsRef<[u8]>>(bytes: T) -> Result<D> {
125 DEFAULT_CONFIG.decode(bytes).await
126}
127
128#[inline]
130pub async fn decode_from<D: Decode, R: Read + Unpin + Send>(reader: R) -> Result<D> {
131 DEFAULT_CONFIG.decode_from(reader).await
132}
133
134#[cfg(test)]
135#[cfg(not(feature = "tokio"))]
136mod tests {
137 use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
138 use std::{
139 collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
140 ffi::CString,
141 };
142
143 use futures_executor as executor;
144 use rand::random;
145
146 use crate::{decode, encode, Encode};
147
148 macro_rules! primitive_test {
149 ($type: ty, $name: ident) => {
150 #[test]
151 fn $name() {
152 executor::block_on(async {
153 let original = random::<$type>();
154 let encoded = encode(&original).await;
155 assert_eq!(original.size(), encoded.len());
156 let decoded: $type = decode(&encoded).await.unwrap();
157 assert_eq!(original, decoded, "Invalid encoding/decoding");
158 });
159 }
160 };
161 }
162
163 primitive_test!(u8, u8_test);
164 primitive_test!(u16, u16_test);
165 primitive_test!(u32, u32_test);
166 primitive_test!(u64, u64_test);
167 primitive_test!(u128, u128_test);
168
169 primitive_test!(i8, i8_test);
170 primitive_test!(i16, i16_test);
171 primitive_test!(i32, i32_test);
172 primitive_test!(i64, i64_test);
173 primitive_test!(i128, i128_test);
174
175 primitive_test!(usize, usize_test);
176 primitive_test!(isize, isize_test);
177 primitive_test!(bool, bool_test);
178 primitive_test!(char, char_test);
179
180 primitive_test!(f32, f32_test);
181 primitive_test!(f64, f64_test);
182
183 primitive_test!(NonZeroU8, non_zero_u8_test);
184 primitive_test!(NonZeroU16, non_zero_u16_test);
185 primitive_test!(NonZeroU32, non_zero_u32_test);
186 primitive_test!(NonZeroU64, non_zero_u64_test);
187 primitive_test!(NonZeroU128, non_zero_u128_test);
188 primitive_test!(NonZeroUsize, non_zero_usize_test);
189
190 primitive_test!([u8; 32], u8_arr_test);
191 primitive_test!([u16; 32], u16_arr_test);
192 primitive_test!([u32; 32], u32_arr_test);
193 primitive_test!([u64; 32], u64_arr_test);
194 primitive_test!([u128; 32], u128_arr_test);
195
196 primitive_test!([i8; 32], i8_arr_test);
197 primitive_test!([i16; 32], i16_arr_test);
198 primitive_test!([i32; 32], i32_arr_test);
199 primitive_test!([i64; 32], i64_arr_test);
200 primitive_test!([i128; 32], i128_arr_test);
201
202 primitive_test!([usize; 32], usize_arr_test);
203 primitive_test!([isize; 32], isize_arr_test);
204 primitive_test!([bool; 32], bool_arr_test);
205 primitive_test!([char; 32], char_arr_test);
206
207 primitive_test!([f32; 32], f32_arr_test);
208 primitive_test!([f64; 32], f64_arr_test);
209
210 #[test]
211 fn option_none_test() {
212 executor::block_on(async {
213 let original: Option<u8> = None;
214 let encoded = encode(&original).await;
215 assert_eq!(original.size(), encoded.len());
216 let decoded: Option<u8> = decode(&encoded).await.unwrap();
217 assert_eq!(original, decoded, "Invalid encoding/decoding");
218 });
219 }
220
221 #[test]
222 fn option_some_test() {
223 executor::block_on(async {
224 let original: Option<u8> = Some(random());
225 let encoded = encode(&original).await;
226 assert_eq!(original.size(), encoded.len());
227 let decoded: Option<u8> = decode(&encoded).await.unwrap();
228 assert_eq!(original, decoded, "Invalid encoding/decoding");
229 });
230 }
231
232 #[test]
233 fn result_ok_test() {
234 executor::block_on(async {
235 let original: Result<u8, u8> = Ok(random());
236 let encoded = encode(&original).await;
237 assert_eq!(original.size(), encoded.len());
238 let decoded: Result<u8, u8> = decode(&encoded).await.unwrap();
239 assert_eq!(original, decoded, "Invalid encoding/decoding");
240 });
241 }
242
243 #[test]
244 fn result_err_test() {
245 executor::block_on(async {
246 let original: Result<u8, u8> = Err(random());
247 let encoded = encode(&original).await;
248 assert_eq!(original.size(), encoded.len());
249 let decoded: Result<u8, u8> = decode(&encoded).await.unwrap();
250 assert_eq!(original, decoded, "Invalid encoding/decoding");
251 });
252 }
253
254 #[test]
255 fn fixed_arr_test() {
256 executor::block_on(async {
257 let original = [1i32, 2i32, 3i32];
258 let encoded = encode(&original).await;
259 assert_eq!(original.size(), encoded.len());
260 let decoded: [i32; 3] = decode(&encoded).await.unwrap();
261 assert_eq!(original, decoded, "Invalid encoding/decoding");
262 });
263 }
264
265 #[test]
266 fn vec_test() {
267 executor::block_on(async {
268 let original = vec![1, 2, 3];
269 let encoded = encode(&original).await;
270 assert_eq!(original.size(), encoded.len());
271 let decoded: Vec<i32> = decode(&encoded).await.unwrap();
272 assert_eq!(original, decoded, "Invalid encoding/decoding");
273 });
274 }
275
276 #[test]
277 fn slice_test() {
278 executor::block_on(async {
279 let original = [1i32, 2i32, 3i32];
280 let encoded = encode(&original[..]).await;
281 assert_eq!(original[..].size(), encoded.len());
282 let decoded: Vec<i32> = decode(&encoded).await.unwrap();
283 assert_eq!(original.to_vec(), decoded, "Invalid encoding/decoding");
284 });
285 }
286
287 #[test]
288 fn string_test() {
289 executor::block_on(async {
290 let original = "hello";
291 let encoded = encode(original).await;
292 assert_eq!(original.size(), encoded.len());
293 let decoded: String = decode(&encoded).await.unwrap();
294 assert_eq!(original.to_string(), decoded, "Invalid encoding/decoding");
295 })
296 }
297
298 #[test]
299 fn c_string_test() {
300 executor::block_on(async {
301 let original = CString::new("hello").unwrap();
302 let encoded = encode(&original).await;
303 assert_eq!(original.size(), encoded.len());
304 let decoded: CString = decode(&encoded).await.unwrap();
305 assert_eq!(original, decoded, "Invalid encoding/decoding");
306 })
307 }
308
309 #[test]
310 fn vec_string_test() {
311 executor::block_on(async {
312 let original = vec!["hello".to_string(), "world".to_string()];
313 let encoded = encode(&original).await;
314 assert_eq!(original.size(), encoded.len());
315 let decoded: Vec<String> = decode(&encoded).await.unwrap();
316 assert_eq!(original, decoded, "Invalid encoding/decoding");
317 })
318 }
319
320 #[test]
321 fn box_test() {
322 executor::block_on(async {
323 let original = Box::new("10".to_string());
324 let encoded = encode(&original).await;
325 assert_eq!(original.size(), encoded.len());
326 let decoded: Box<String> = decode(&encoded).await.unwrap();
327 assert_eq!(original, decoded, "Invalid encoding/decoding");
328 });
329 }
330
331 #[test]
332 fn tuple_test() {
333 executor::block_on(async {
334 let original = ("hello".to_string(), 25u8, 100i32);
335 let encoded = encode(&original).await;
336 assert_eq!(original.size(), encoded.len());
337 let decoded: (String, u8, i32) = decode(&encoded).await.unwrap();
338 assert_eq!(original, decoded, "Invalid encoding/decoding");
339 });
340 }
341
342 #[test]
343 fn vec_deque_test() {
344 executor::block_on(async {
345 let mut original = VecDeque::with_capacity(3);
346 original.push_back(1);
347 original.push_back(2);
348 original.push_back(3);
349 let encoded = encode(&original).await;
350 assert_eq!(original.size(), encoded.len());
351 let decoded: VecDeque<i32> = decode(&encoded).await.unwrap();
352 assert_eq!(original, decoded, "Invalid encoding/decoding");
353 });
354 }
355
356 #[test]
357 fn linked_list_test() {
358 executor::block_on(async {
359 let mut original = LinkedList::new();
360 original.push_back(1);
361 original.push_back(2);
362 original.push_back(3);
363 let encoded = encode(&original).await;
364 assert_eq!(original.size(), encoded.len());
365 let decoded: LinkedList<i32> = decode(&encoded).await.unwrap();
366 assert_eq!(original, decoded, "Invalid encoding/decoding");
367 });
368 }
369
370 #[test]
371 fn hash_set_test() {
372 executor::block_on(async {
373 let mut original = HashSet::with_capacity(3);
374 original.insert(1);
375 original.insert(2);
376 original.insert(3);
377 let encoded = encode(&original).await;
378 assert_eq!(original.size(), encoded.len());
379 let decoded: HashSet<i32> = decode(&encoded).await.unwrap();
380 assert_eq!(original, decoded, "Invalid encoding/decoding");
381 });
382 }
383
384 #[test]
385 fn btree_set_test() {
386 executor::block_on(async {
387 let mut original = BTreeSet::new();
388 original.insert(3);
389 original.insert(1);
390 original.insert(2);
391 let encoded = encode(&original).await;
392 assert_eq!(original.size(), encoded.len());
393 let decoded: BTreeSet<i32> = decode(&encoded).await.unwrap();
394 assert_eq!(original, decoded, "Invalid encoding/decoding");
395 });
396 }
397
398 #[test]
399 fn binary_heap_test() {
400 executor::block_on(async {
401 let mut original: BinaryHeap<i32> = BinaryHeap::new();
402 original.push(3);
403 original.push(1);
404 original.push(2);
405 let encoded = encode(&original).await;
406 assert_eq!(original.size(), encoded.len());
407 let decoded: BinaryHeap<i32> = decode(&encoded).await.unwrap();
408 let new_encoded = encode(&decoded).await;
409 assert_eq!(encoded, new_encoded, "Invalid encoding/decoding");
410 });
411 }
412
413 #[test]
414 fn hash_map_test() {
415 executor::block_on(async {
416 let mut original = HashMap::with_capacity(3);
417 original.insert(1, "Hello".to_owned());
418 original.insert(2, "World".to_owned());
419 original.insert(3, "!".to_owned());
420 let encoded = encode(&original).await;
421 assert_eq!(original.size(), encoded.len());
422 let decoded: HashMap<i32, String> = decode(&encoded).await.unwrap();
423 assert_eq!(original, decoded, "Invalid encoding/decoding");
424 });
425 }
426
427 #[test]
428 fn btree_map_test() {
429 executor::block_on(async {
430 let mut original = BTreeMap::new();
431 original.insert(1, "Hello".to_owned());
432 original.insert(2, "World".to_owned());
433 original.insert(3, "!".to_owned());
434 let encoded = encode(&original).await;
435 assert_eq!(original.size(), encoded.len());
436 let decoded: BTreeMap<i32, String> = decode(&encoded).await.unwrap();
437 assert_eq!(original, decoded, "Invalid encoding/decoding");
438 });
439 }
440}