fixed_bigint/heapless/from_prim.rs
1//! `From<u8>` / `From<u16>` / `From<u32>` for `HeaplessBigInt`.
2//!
3//! Small-value constructors. Output `len` is fixed by the source
4//! primitive width (`ceil(size_of::<uN>() / size_of::<T>())`), not by
5//! the value — so the shape is public. Under-sized capacity (`CAP` too
6//! small to hold the source primitive) triggers `from_le_bytes`'s
7//! runtime assertion; matches `FixedUInt`'s implicit contract.
8//!
9//! This is the source-int width, which is likely narrower than the width
10//! a downstream computation needs — see the construction-width table in
11//! the [module docs](super). To carry the value at a chosen width, pin it
12//! with [`WithPrecision`](const_num_traits::WithPrecision) (e.g.
13//! `From::from(v).widen_to_precision_of(&modulus)`).
14
15use super::HeaplessBigInt;
16use crate::MachineWord;
17use const_num_traits::Personality;
18
19macro_rules! from_primitive {
20 ($($t:ty),+) => { $(
21 impl<T: MachineWord, const CAP: usize, P: Personality> From<$t> for HeaplessBigInt<T, CAP, P> {
22 fn from(v: $t) -> Self {
23 Self::from_le_bytes(&v.to_le_bytes())
24 }
25 }
26 )+ };
27}
28
29from_primitive!(u8, u16, u32, u64);
30
31#[cfg(test)]
32mod tests {
33 use super::HeaplessBigInt;
34
35 #[test]
36 fn from_u64_source_width() {
37 // From<u64> constructs at the source-int width (8 bytes → 2 u32 limbs).
38 let v: HeaplessBigInt<u32, 8> = 0x1234_5678_9ABCu64.into();
39 assert_eq!(v.len(), 2);
40 assert_eq!(v.limbs()[0], 0x5678_9ABC);
41 assert_eq!(v.limbs()[1], 0x0000_1234);
42 }
43}