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