spl_pod/
pod_length.rs

1use {
2    crate::{
3        error::PodSliceError,
4        primitives::{PodU128, PodU16, PodU32, PodU64},
5    },
6    bytemuck::Pod,
7};
8
9/// Marker trait for converting to/from Pod `uint`'s and `usize`
10pub trait PodLength: Pod + Into<usize> + TryFrom<usize, Error = PodSliceError> {}
11
12/// Blanket implementation to automatically implement `PodLength` for any type
13/// that satisfies the required bounds.
14impl<T> PodLength for T where T: Pod + Into<usize> + TryFrom<usize, Error = PodSliceError> {}
15
16/// Implements the `TryFrom<usize>` and `From<T> for usize` conversions for a Pod integer type
17macro_rules! impl_pod_length_for {
18    ($PodType:ty, $PrimitiveType:ty) => {
19        impl TryFrom<usize> for $PodType {
20            type Error = PodSliceError;
21
22            fn try_from(val: usize) -> Result<Self, Self::Error> {
23                let primitive_val = <$PrimitiveType>::try_from(val)?;
24                Ok(primitive_val.into())
25            }
26        }
27
28        impl From<$PodType> for usize {
29            fn from(pod_val: $PodType) -> Self {
30                let primitive_val = <$PrimitiveType>::from(pod_val);
31                Self::try_from(primitive_val)
32                    .expect("value out of range for usize on this platform")
33            }
34        }
35    };
36}
37
38impl_pod_length_for!(PodU16, u16);
39impl_pod_length_for!(PodU32, u32);
40impl_pod_length_for!(PodU64, u64);
41impl_pod_length_for!(PodU128, u128);