1#[cfg(feature = "alloc")]
2extern crate alloc;
3
4#[cfg(feature = "alloc")]
5use alloc::{boxed::Box, rc::Rc};
6
7#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
8use alloc::sync::Arc;
9
10use crate::varint::varint_max;
11use core::{
12 marker::PhantomData,
13 num::{
14 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128,
15 NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize,
16 },
17 ops::{Range, RangeFrom, RangeInclusive, RangeTo},
18 time::Duration,
19};
20
21pub trait MaxSize {
24 const POSTCARD_MAX_SIZE: usize;
27}
28
29impl MaxSize for bool {
30 const POSTCARD_MAX_SIZE: usize = 1;
31}
32
33impl MaxSize for i8 {
34 const POSTCARD_MAX_SIZE: usize = 1;
35}
36
37impl MaxSize for i16 {
38 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
39}
40
41impl MaxSize for i32 {
42 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
43}
44
45impl MaxSize for i64 {
46 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
47}
48
49impl MaxSize for i128 {
50 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
51}
52
53impl MaxSize for isize {
54 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
55}
56
57impl MaxSize for u8 {
58 const POSTCARD_MAX_SIZE: usize = 1;
59}
60
61impl MaxSize for u16 {
62 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
63}
64
65impl MaxSize for u32 {
66 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
67}
68
69impl MaxSize for u64 {
70 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
71}
72
73impl MaxSize for u128 {
74 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
75}
76
77impl MaxSize for usize {
78 const POSTCARD_MAX_SIZE: usize = varint_max::<Self>();
79}
80
81impl MaxSize for f32 {
82 const POSTCARD_MAX_SIZE: usize = 4;
83}
84
85impl MaxSize for f64 {
86 const POSTCARD_MAX_SIZE: usize = 8;
87}
88
89impl MaxSize for char {
90 const POSTCARD_MAX_SIZE: usize = 5;
91}
92
93impl<T: MaxSize> MaxSize for Option<T> {
94 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE + 1;
95}
96
97impl<T: MaxSize, E: MaxSize> MaxSize for Result<T, E> {
98 const POSTCARD_MAX_SIZE: usize = max(T::POSTCARD_MAX_SIZE, E::POSTCARD_MAX_SIZE) + 1;
99}
100
101impl MaxSize for () {
102 const POSTCARD_MAX_SIZE: usize = 0;
103}
104
105impl<T: MaxSize, const N: usize> MaxSize for [T; N] {
106 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE * N;
107}
108
109impl<T: MaxSize> MaxSize for &'_ T {
110 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
111}
112
113impl<T: MaxSize> MaxSize for &'_ mut T {
114 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
115}
116
117impl MaxSize for NonZeroI8 {
118 const POSTCARD_MAX_SIZE: usize = i8::POSTCARD_MAX_SIZE;
119}
120
121impl MaxSize for NonZeroI16 {
122 const POSTCARD_MAX_SIZE: usize = i16::POSTCARD_MAX_SIZE;
123}
124
125impl MaxSize for NonZeroI32 {
126 const POSTCARD_MAX_SIZE: usize = i32::POSTCARD_MAX_SIZE;
127}
128
129impl MaxSize for NonZeroI64 {
130 const POSTCARD_MAX_SIZE: usize = i64::POSTCARD_MAX_SIZE;
131}
132
133impl MaxSize for NonZeroI128 {
134 const POSTCARD_MAX_SIZE: usize = i128::POSTCARD_MAX_SIZE;
135}
136
137impl MaxSize for NonZeroIsize {
138 const POSTCARD_MAX_SIZE: usize = isize::POSTCARD_MAX_SIZE;
139}
140
141impl MaxSize for NonZeroU8 {
142 const POSTCARD_MAX_SIZE: usize = u8::POSTCARD_MAX_SIZE;
143}
144
145impl MaxSize for NonZeroU16 {
146 const POSTCARD_MAX_SIZE: usize = u16::POSTCARD_MAX_SIZE;
147}
148
149impl MaxSize for NonZeroU32 {
150 const POSTCARD_MAX_SIZE: usize = u32::POSTCARD_MAX_SIZE;
151}
152
153impl MaxSize for NonZeroU64 {
154 const POSTCARD_MAX_SIZE: usize = u64::POSTCARD_MAX_SIZE;
155}
156
157impl MaxSize for NonZeroU128 {
158 const POSTCARD_MAX_SIZE: usize = u128::POSTCARD_MAX_SIZE;
159}
160
161impl MaxSize for NonZeroUsize {
162 const POSTCARD_MAX_SIZE: usize = usize::POSTCARD_MAX_SIZE;
163}
164
165impl MaxSize for Duration {
166 const POSTCARD_MAX_SIZE: usize = u64::POSTCARD_MAX_SIZE + u32::POSTCARD_MAX_SIZE;
167}
168
169impl<T> MaxSize for PhantomData<T> {
170 const POSTCARD_MAX_SIZE: usize = 0;
171}
172
173impl<A: MaxSize> MaxSize for (A,) {
174 const POSTCARD_MAX_SIZE: usize = A::POSTCARD_MAX_SIZE;
175}
176
177impl<A: MaxSize, B: MaxSize> MaxSize for (A, B) {
178 const POSTCARD_MAX_SIZE: usize = A::POSTCARD_MAX_SIZE + B::POSTCARD_MAX_SIZE;
179}
180
181impl<A: MaxSize, B: MaxSize, C: MaxSize> MaxSize for (A, B, C) {
182 const POSTCARD_MAX_SIZE: usize =
183 A::POSTCARD_MAX_SIZE + B::POSTCARD_MAX_SIZE + C::POSTCARD_MAX_SIZE;
184}
185
186impl<A: MaxSize, B: MaxSize, C: MaxSize, D: MaxSize> MaxSize for (A, B, C, D) {
187 const POSTCARD_MAX_SIZE: usize =
188 A::POSTCARD_MAX_SIZE + B::POSTCARD_MAX_SIZE + C::POSTCARD_MAX_SIZE + D::POSTCARD_MAX_SIZE;
189}
190
191impl<A: MaxSize, B: MaxSize, C: MaxSize, D: MaxSize, E: MaxSize> MaxSize for (A, B, C, D, E) {
192 const POSTCARD_MAX_SIZE: usize = A::POSTCARD_MAX_SIZE
193 + B::POSTCARD_MAX_SIZE
194 + C::POSTCARD_MAX_SIZE
195 + D::POSTCARD_MAX_SIZE
196 + E::POSTCARD_MAX_SIZE;
197}
198
199impl<A: MaxSize, B: MaxSize, C: MaxSize, D: MaxSize, E: MaxSize, F: MaxSize> MaxSize
200 for (A, B, C, D, E, F)
201{
202 const POSTCARD_MAX_SIZE: usize = A::POSTCARD_MAX_SIZE
203 + B::POSTCARD_MAX_SIZE
204 + C::POSTCARD_MAX_SIZE
205 + D::POSTCARD_MAX_SIZE
206 + E::POSTCARD_MAX_SIZE
207 + F::POSTCARD_MAX_SIZE;
208}
209
210impl<T: MaxSize> MaxSize for Range<T> {
211 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE * 2;
212}
213
214impl<T: MaxSize> MaxSize for RangeInclusive<T> {
215 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE * 2;
216}
217
218impl<T: MaxSize> MaxSize for RangeFrom<T> {
219 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
220}
221
222impl<T: MaxSize> MaxSize for RangeTo<T> {
223 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
224}
225
226impl<T: MaxSize> MaxSize for core::num::Wrapping<T> {
227 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
228}
229
230#[cfg(all(feature = "core-num-saturating", feature = "experimental-derive"))]
231#[cfg_attr(docsrs, doc(cfg(feature = "core-num-saturating")))]
232impl<T: MaxSize> MaxSize for core::num::Saturating<T> {
233 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
234}
235
236#[cfg(feature = "alloc")]
237#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
238impl<T: MaxSize> MaxSize for Box<T> {
239 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
240}
241
242#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
243#[cfg_attr(docsrs, doc(cfg(all(feature = "alloc", target_has_atomic = "ptr"))))]
244impl<T: MaxSize> MaxSize for Arc<T> {
245 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
246}
247
248#[cfg(feature = "alloc")]
249#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
250impl<T: MaxSize> MaxSize for Rc<T> {
251 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
252}
253
254#[cfg(feature = "heapless")]
255#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))]
256impl<T: MaxSize, const N: usize> MaxSize for heapless::Vec<T, N> {
257 const POSTCARD_MAX_SIZE: usize = <[T; N]>::POSTCARD_MAX_SIZE + varint_size(N);
258}
259
260#[cfg(feature = "heapless")]
261#[cfg_attr(docsrs, doc(cfg(feature = "heapless")))]
262impl<const N: usize> MaxSize for heapless::String<N> {
263 const POSTCARD_MAX_SIZE: usize = <[u8; N]>::POSTCARD_MAX_SIZE + varint_size(N);
264}
265
266#[cfg(all(feature = "nalgebra-v0_33", feature = "experimental-derive"))]
267#[cfg_attr(docsrs, doc(cfg(feature = "nalgebra-v0_33")))]
268impl<T, const R: usize, const C: usize> MaxSize
269 for nalgebra_v0_33::Matrix<
270 T,
271 nalgebra_v0_33::Const<R>,
272 nalgebra_v0_33::Const<C>,
273 nalgebra_v0_33::ArrayStorage<T, R, C>,
274 >
275where
276 T: MaxSize + nalgebra_v0_33::Scalar,
277{
278 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE * R * C;
279}
280
281#[cfg(all(feature = "nalgebra-v0_33", feature = "experimental-derive"))]
282#[cfg_attr(docsrs, doc(cfg(feature = "nalgebra-v0_33")))]
283impl<T: MaxSize> MaxSize for nalgebra_v0_33::Unit<T> {
284 const POSTCARD_MAX_SIZE: usize = T::POSTCARD_MAX_SIZE;
285}
286
287#[cfg(all(feature = "nalgebra-v0_33", feature = "experimental-derive"))]
288#[cfg_attr(docsrs, doc(cfg(feature = "nalgebra-v0_33")))]
289impl<T: MaxSize + nalgebra_v0_33::Scalar> MaxSize for nalgebra_v0_33::Quaternion<T> {
290 const POSTCARD_MAX_SIZE: usize = nalgebra_v0_33::Vector4::<T>::POSTCARD_MAX_SIZE;
291}
292
293#[cfg(feature = "heapless")]
294const fn varint_size(max_n: usize) -> usize {
295 const BITS_PER_BYTE: usize = 8;
296 const BITS_PER_VARINT_BYTE: usize = 7;
297
298 if max_n == 0 {
299 return 1;
300 }
301
302 let bits = core::mem::size_of::<usize>() * BITS_PER_BYTE - max_n.leading_zeros() as usize;
304
305 let roundup_bits = bits + (BITS_PER_VARINT_BYTE - 1);
309
310 roundup_bits / BITS_PER_VARINT_BYTE
312}
313
314const fn max(lhs: usize, rhs: usize) -> usize {
315 if lhs > rhs {
316 lhs
317 } else {
318 rhs
319 }
320}
321
322#[cfg(any(feature = "alloc", feature = "use-std"))]
323#[cfg(test)]
324mod tests {
325 extern crate alloc;
326
327 use super::*;
328 use alloc::rc::Rc;
329
330 #[cfg(target_has_atomic = "ptr")]
331 use alloc::sync::Arc;
332
333 #[test]
334 fn box_max_size() {
335 assert_eq!(Box::<u8>::POSTCARD_MAX_SIZE, 1);
336 assert_eq!(Box::<u32>::POSTCARD_MAX_SIZE, 5);
337 assert_eq!(Box::<(u128, [u8; 8])>::POSTCARD_MAX_SIZE, 27);
338 }
339
340 #[test]
341 #[cfg(target_has_atomic = "ptr")]
342 fn arc_max_size() {
343 assert_eq!(Arc::<u8>::POSTCARD_MAX_SIZE, 1);
344 assert_eq!(Arc::<u32>::POSTCARD_MAX_SIZE, 5);
345 assert_eq!(Arc::<(u128, [u8; 8])>::POSTCARD_MAX_SIZE, 27);
346 }
347
348 #[test]
349 fn rc_max_size() {
350 assert_eq!(Rc::<u8>::POSTCARD_MAX_SIZE, 1);
351 assert_eq!(Rc::<u32>::POSTCARD_MAX_SIZE, 5);
352 assert_eq!(Rc::<(u128, [u8; 8])>::POSTCARD_MAX_SIZE, 27);
353 }
354}