1use core::{
2 fmt::{Debug, Display},
3 ops::{Add, AddAssign, Sub, SubAssign},
4};
5
6#[cfg(feature = "zeroize")]
7use zeroize::Zeroize;
8
9pub trait Sealed:
10 Send
11 + Sync
12 + Copy
13 + Display
14 + Debug
15 + PartialEq
16 + Add<Output = Self>
17 + AddAssign
18 + Sub<Output = Self>
19 + SubAssign
20 + PartialOrd
21 + TryFrom<usize, Error: Debug>
22 + TryInto<usize, Error: Debug>
23{
24 const ZERO: Self;
26 const MAX: Self;
28 const MAX_USIZE: usize;
30
31 fn one() -> Self;
36
37 #[inline]
39 fn from_usize(val: usize) -> Self {
40 val.try_into().unwrap()
41 }
42
43 #[inline]
45 fn into_usize(self) -> usize {
46 self.try_into().unwrap()
47 }
48
49 #[inline]
51 fn to_non_max(self) -> Option<usize> {
52 if self == Self::MAX {
53 None
54 } else {
55 Some(self.into_usize())
56 }
57 }
58}
59
60macro_rules! impl_lentype {
61 ($($(#[$meta:meta])* $LenT:ty),*) => {$(
62 $(#[$meta])*
63 impl Sealed for $LenT {
64 const ZERO: Self = 0;
65 const MAX: Self = Self::MAX;
66 const MAX_USIZE: usize = Self::MAX as _;
67
68 fn one() -> Self {
69 1
70 }
71 }
72
73 $(#[$meta])*
74 impl LenType for $LenT {}
75 )*}
76}
77
78#[cfg(feature = "zeroize")]
84pub trait LenType: Sealed + Zeroize {}
85
86#[cfg(not(feature = "zeroize"))]
90pub trait LenType: Sealed {}
91
92impl_lentype!(
93 u8,
94 u16,
95 #[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
96 u32,
97 usize
98);
99
100pub const fn check_capacity_fits<LenT: LenType, const N: usize>() {
101 assert!(LenT::MAX_USIZE >= N, "The capacity is larger than `LenT` can hold, increase the size of `LenT` or reduce the capacity");
102}