desse/lib.rs
1#![deny(missing_docs)]
2//! Ultra fast binary serialization and deserialization for types with a constant size (known at compile time). This
3//! crate cannot be used to serialize or deserialize dynamically allocated types, such as,
4//! [`String`](std::string::String), [`Vec`](std::vec::Vec), [`HashMap`](std::collections::HashMap), etc., and types
5//! with unknown size at compile time such as [`slice`](std::slice), [`&str`](std::str), etc.
6//!
7//! ## Binary Encoding Scheme
8//!
9//! This crate uses a minimal binary encoding scheme such that the size of encoded object will be smaller than (in cases
10//! where Rust adds padding bytes for alignment) or equal to it's size in a running Rust program. For example, consider
11//! the following `struct`:
12//!
13//! ```
14//! struct MyStruct {
15//! a: u8,
16//! b: u16,
17//! }
18//! ```
19//!
20//! `Desse::serialize` will serialize this struct in `[u8; 3]` where `3` is the sum of sizes of `u8` and `u16`.
21//!
22//! ## Usage
23//!
24//! `Desse` trait can be implemented for any struct or enum (whose size is known at compile time) using `derive` macro.
25//! This crate also provides a `derive` macro for implementing `DesseSized` trait which is necessary for implementing
26//! `Desse` trait.
27//! ```
28//! use desse::{Desse, DesseSized};
29//!
30//! #[derive(Debug, PartialEq, Desse, DesseSized)]
31//! struct MyStruct {
32//! a: u8,
33//! b: u16,
34//! }
35//! ```
36//!
37//! Now, you can use `Desse::serialize` and `Desse::deserialize_from` for serialization and deserialization of this
38//! struct.
39//!
40//! ```
41//! # use desse::{Desse, DesseSized};
42//! #
43//! # #[derive(Debug, PartialEq, Desse, DesseSized)]
44//! # struct MyStruct {
45//! # a: u8,
46//! # b: u16,
47//! # }
48//! #
49//! let my_struct = MyStruct { a: 5, b: 1005 };
50//! let serialized: [u8; 3] = my_struct.serialize();
51//! let new_struct = MyStruct::deserialize_from(&serialized);
52//!
53//! assert_eq!(my_struct, new_struct);
54//! ```
55//!
56//! Note that `Desse::serialize` returns an array of fixed length (`3` in above case) and `Desse::deserialize` takes
57//! reference to an array of fixed length as argument.
58
59#![no_std]
60
61mod desse;
62
63pub use crate::desse::{Desse, DesseSized};
64
65#[cfg(feature = "derive")]
66pub use desse_derive::*;
67
68/// Compares and returns maximum of two values.
69///
70/// # Warning
71///
72/// This function internally uses bitwise operations to find maximum value, which, in some cases, may not be best
73/// approach. But, Rust's [`max()`](https://doc.rust-lang.org/nightly/std/cmp/fn.max.html) is not a `const fn` which is
74/// needed for compile time evaluation of `max` value.
75///
76/// The need for this function will go away once [`const fn`](https://github.com/rust-lang/rust/issues/57563) fully
77/// lands in stable and `max()` becomes a `const fn`.
78pub const fn max(x: usize, y: usize) -> usize {
79 let x = x as i128;
80 let y = y as i128;
81
82 (x ^ ((x ^ y) & -((x < y) as i128))) as usize
83}