Skip to main content

bincode_next/features/
static_size.rs

1//! Static size trait for compile-time memory bound validation.
2
3/// A trait that calculates the upper bound of a type's serialized size as a `const` value.
4pub trait StaticSize {
5    /// The maximum possible serialized size in bytes (no bit-packing).
6    const MAX_SIZE: usize;
7    /// The maximum possible serialized size in bytes when bit-packing is enabled.
8    ///
9    /// For types with `#[bincode(bits = N)]` fields this is typically smaller than
10    /// `MAX_SIZE` because consecutive bit-packed fields share bytes.  Types that
11    /// have no bit-packed fields default to `MAX_SIZE`.
12    const PACKED_MAX_SIZE: usize = Self::MAX_SIZE;
13}
14
15// Primitives
16impl StaticSize for bool {
17    const MAX_SIZE: usize = 1;
18}
19impl StaticSize for u8 {
20    const MAX_SIZE: usize = 1;
21}
22impl StaticSize for i8 {
23    const MAX_SIZE: usize = 1;
24}
25
26impl StaticSize for u16 {
27    const MAX_SIZE: usize = 3;
28}
29impl StaticSize for i16 {
30    const MAX_SIZE: usize = 3;
31}
32impl StaticSize for u32 {
33    const MAX_SIZE: usize = 5;
34}
35impl StaticSize for i32 {
36    const MAX_SIZE: usize = 5;
37}
38impl StaticSize for u64 {
39    const MAX_SIZE: usize = 9;
40}
41impl StaticSize for i64 {
42    const MAX_SIZE: usize = 9;
43}
44impl StaticSize for u128 {
45    const MAX_SIZE: usize = 17;
46}
47impl StaticSize for i128 {
48    const MAX_SIZE: usize = 17;
49}
50impl StaticSize for usize {
51    const MAX_SIZE: Self = 9;
52}
53impl StaticSize for isize {
54    const MAX_SIZE: usize = 9;
55}
56
57impl StaticSize for f32 {
58    const MAX_SIZE: usize = 4;
59}
60impl StaticSize for f64 {
61    const MAX_SIZE: usize = 8;
62}
63impl StaticSize for char {
64    const MAX_SIZE: usize = 4;
65}
66impl StaticSize for () {
67    const MAX_SIZE: usize = 0;
68}
69
70impl<T> StaticSize for core::marker::PhantomData<T> {
71    const MAX_SIZE: usize = 0;
72}
73
74// Arrays
75impl<T: StaticSize, const N: usize> StaticSize for [T; N] {
76    const MAX_SIZE: usize = T::MAX_SIZE * N;
77}
78
79// Option
80impl<T: StaticSize> StaticSize for Option<T> {
81    const MAX_SIZE: usize = 1 + T::MAX_SIZE;
82}
83
84// Result
85impl<T: StaticSize, E: StaticSize> StaticSize for Result<T, E> {
86    const MAX_SIZE: usize = 5
87        + (if T::MAX_SIZE > E::MAX_SIZE {
88            T::MAX_SIZE
89        } else {
90            E::MAX_SIZE
91        });
92}
93
94// Tuples
95macro_rules! impl_static_size_tuple {
96    ($($name:ident),*) => {
97        impl<$($name: StaticSize),*> StaticSize for ($($name,)*) {
98            const MAX_SIZE: usize = 0 $(+ $name::MAX_SIZE)*;
99        }
100    }
101}
102
103impl_static_size_tuple!(A);
104impl_static_size_tuple!(A, B);
105impl_static_size_tuple!(A, B, C);
106impl_static_size_tuple!(A, B, C, D);
107impl_static_size_tuple!(A, B, C, D, E);
108impl_static_size_tuple!(A, B, C, D, E, F);
109impl_static_size_tuple!(A, B, C, D, E, F, G);
110impl_static_size_tuple!(A, B, C, D, E, F, G, H);
111impl_static_size_tuple!(A, B, C, D, E, F, G, H, I);
112impl_static_size_tuple!(A, B, C, D, E, F, G, H, I, J);
113impl_static_size_tuple!(A, B, C, D, E, F, G, H, I, J, K);
114impl_static_size_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
115
116/// Helper constants for common bincode structures
117#[doc(hidden)]
118pub mod helpers {
119    /// The maximum bytes a `usize` (length) can take when encoded as a varint.
120    pub const VARINT_MAX_64: usize = 9;
121    /// The maximum bytes a `u32` can take when encoded as a varint.
122    pub const VARINT_MAX_32: usize = 5;
123}