parity_scale_codec/
max_encoded_len.rs1use crate::{Compact, Encode};
19use impl_trait_for_tuples::impl_for_tuples;
20use core::{mem, marker::PhantomData, num::*, ops::{Range, RangeInclusive}, time::Duration};
21use crate::alloc::boxed::Box;
22
23#[cfg(target_has_atomic = "ptr")]
24use crate::alloc::sync::Arc;
25
26pub trait MaxEncodedLen: Encode {
33 fn max_encoded_len() -> usize;
35}
36
37macro_rules! impl_primitives {
38 ( $($t:ty),+ ) => {
39 $(
40 impl MaxEncodedLen for $t {
41 fn max_encoded_len() -> usize {
42 mem::size_of::<$t>()
43 }
44 }
45 )+
46 };
47}
48
49impl_primitives!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128, bool);
50
51impl_primitives!(
52 NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU128, NonZeroI8, NonZeroI16, NonZeroI32,
53 NonZeroI64, NonZeroI128
54);
55
56macro_rules! impl_compact {
57 ($( $t:ty => $e:expr; )*) => {
58 $(
59 impl MaxEncodedLen for Compact<$t> {
60 fn max_encoded_len() -> usize {
61 $e
62 }
63 }
64 )*
65 };
66}
67
68impl_compact!(
69 () => 0;
70 u8 => 2;
72 u16 => 4;
74 u32 => 5;
76 u64 => 9;
78 u128 => 17;
80);
81
82#[impl_for_tuples(18)]
84impl MaxEncodedLen for Tuple {
85 fn max_encoded_len() -> usize {
86 let mut len: usize = 0;
87 for_tuples!( #( len = len.saturating_add(Tuple::max_encoded_len()); )* );
88 len
89 }
90}
91
92impl<T: MaxEncodedLen, const N: usize> MaxEncodedLen for [T; N] {
93 fn max_encoded_len() -> usize {
94 T::max_encoded_len().saturating_mul(N)
95 }
96}
97
98impl<T: MaxEncodedLen> MaxEncodedLen for Box<T> {
99 fn max_encoded_len() -> usize {
100 T::max_encoded_len()
101 }
102}
103
104#[cfg(target_has_atomic = "ptr")]
105impl<T: MaxEncodedLen> MaxEncodedLen for Arc<T> {
106 fn max_encoded_len() -> usize {
107 T::max_encoded_len()
108 }
109}
110
111impl<T: MaxEncodedLen> MaxEncodedLen for Option<T> {
112 fn max_encoded_len() -> usize {
113 T::max_encoded_len().saturating_add(1)
114 }
115}
116
117impl<T, E> MaxEncodedLen for Result<T, E>
118where
119 T: MaxEncodedLen,
120 E: MaxEncodedLen,
121{
122 fn max_encoded_len() -> usize {
123 T::max_encoded_len().max(E::max_encoded_len()).saturating_add(1)
124 }
125}
126
127impl<T> MaxEncodedLen for PhantomData<T> {
128 fn max_encoded_len() -> usize {
129 0
130 }
131}
132
133impl MaxEncodedLen for Duration {
134 fn max_encoded_len() -> usize {
135 u64::max_encoded_len() + u32::max_encoded_len()
136 }
137}
138
139impl<T: MaxEncodedLen> MaxEncodedLen for Range<T> {
140 fn max_encoded_len() -> usize {
141 T::max_encoded_len().saturating_mul(2)
142 }
143}
144
145impl<T: MaxEncodedLen> MaxEncodedLen for RangeInclusive<T> {
146 fn max_encoded_len() -> usize {
147 T::max_encoded_len().saturating_mul(2)
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 macro_rules! test_compact_length {
156 ($(fn $name:ident($t:ty);)*) => {
157 $(
158 #[test]
159 fn $name() {
160 assert_eq!(Compact(<$t>::MAX).encode().len(), Compact::<$t>::max_encoded_len());
161 }
162 )*
163 };
164 }
165
166 test_compact_length!(
167 fn compact_u8(u8);
168 fn compact_u16(u16);
169 fn compact_u32(u32);
170 fn compact_u64(u64);
171 fn compact_u128(u128);
172 );
173}