Skip to main content

crypto_bigint/uint/boxed/
from.rs

1//! `From`-like conversions for [`BoxedUint`].
2
3use crate::{BoxedUint, Limb, Odd, U64, U128, Uint, UintRef, Word};
4use alloc::{boxed::Box, vec::Vec};
5use core::mem;
6
7impl From<u8> for BoxedUint {
8    fn from(n: u8) -> Self {
9        vec![Limb::from(n); 1].into()
10    }
11}
12
13impl From<u16> for BoxedUint {
14    fn from(n: u16) -> Self {
15        vec![Limb::from(n); 1].into()
16    }
17}
18
19impl From<u32> for BoxedUint {
20    fn from(n: u32) -> Self {
21        vec![Limb::from(n); 1].into()
22    }
23}
24
25impl From<u64> for BoxedUint {
26    fn from(n: u64) -> Self {
27        U64::from(n).into()
28    }
29}
30
31impl From<u128> for BoxedUint {
32    fn from(n: u128) -> Self {
33        U128::from(n).into()
34    }
35}
36
37impl From<Limb> for BoxedUint {
38    fn from(limb: Limb) -> Self {
39        vec![limb; 1].into()
40    }
41}
42
43impl From<&[Limb]> for BoxedUint {
44    fn from(limbs: &[Limb]) -> BoxedUint {
45        Self {
46            limbs: limbs.into(),
47        }
48    }
49}
50
51impl From<Box<[Limb]>> for BoxedUint {
52    fn from(limbs: Box<[Limb]>) -> BoxedUint {
53        Vec::from(limbs).into()
54    }
55}
56
57impl From<Vec<Limb>> for BoxedUint {
58    fn from(mut limbs: Vec<Limb>) -> BoxedUint {
59        if limbs.is_empty() {
60            limbs.push(Limb::ZERO);
61        }
62
63        Self {
64            limbs: limbs.into_boxed_slice(),
65        }
66    }
67}
68
69impl From<Vec<Word>> for BoxedUint {
70    fn from(mut words: Vec<Word>) -> BoxedUint {
71        // SAFETY: `Limb` is a `repr(transparent)` newtype for `Word`
72        #[allow(unsafe_code)]
73        unsafe {
74            let ptr = words.as_mut_ptr().cast::<Limb>();
75            let len = words.len();
76            let capacity = words.capacity();
77            mem::forget(words);
78            Vec::<Limb>::from_raw_parts(ptr, len, capacity)
79        }
80        .into()
81    }
82}
83
84impl<const LIMBS: usize> From<Uint<LIMBS>> for BoxedUint {
85    #[inline]
86    fn from(uint: Uint<LIMBS>) -> BoxedUint {
87        Self::from(&uint)
88    }
89}
90
91impl<const LIMBS: usize> From<&Uint<LIMBS>> for BoxedUint {
92    #[inline]
93    fn from(uint: &Uint<LIMBS>) -> BoxedUint {
94        Vec::from(uint.to_limbs()).into()
95    }
96}
97
98impl<const LIMBS: usize> From<Odd<Uint<LIMBS>>> for BoxedUint {
99    #[inline]
100    fn from(uint: Odd<Uint<LIMBS>>) -> BoxedUint {
101        Self::from(uint.as_ref())
102    }
103}
104
105impl<const LIMBS: usize> From<&Odd<Uint<LIMBS>>> for BoxedUint {
106    #[inline]
107    fn from(uint: &Odd<Uint<LIMBS>>) -> BoxedUint {
108        Self::from(uint.as_ref())
109    }
110}
111
112impl<const LIMBS: usize> From<Odd<Uint<LIMBS>>> for Odd<BoxedUint> {
113    #[inline]
114    fn from(uint: Odd<Uint<LIMBS>>) -> Odd<BoxedUint> {
115        Odd::new_unchecked(BoxedUint::from(uint.as_ref()))
116    }
117}
118
119impl<const LIMBS: usize> From<&Odd<Uint<LIMBS>>> for Odd<BoxedUint> {
120    #[inline]
121    fn from(uint: &Odd<Uint<LIMBS>>) -> Odd<BoxedUint> {
122        Odd::new_unchecked(BoxedUint::from(uint.as_ref()))
123    }
124}
125
126impl From<&UintRef> for BoxedUint {
127    fn from(uint_ref: &UintRef) -> BoxedUint {
128        debug_assert!(uint_ref.nlimbs() >= 1, "empty `UintRef`");
129        BoxedUint {
130            limbs: uint_ref.as_limbs().into(),
131        }
132    }
133}
134
135#[cfg(test)]
136mod tests {
137    use alloc::vec::Vec;
138
139    use crate::{BoxedUint, Limb, Odd, U256};
140
141    #[test]
142    fn from_limb_slice() {
143        let n = BoxedUint::from(&[Limb(42), Limb::MAX][..]);
144        assert_eq!(n.as_limbs(), &[Limb(42), Limb::MAX]);
145    }
146
147    #[test]
148    fn from_boxed_limb_slice() {
149        let n = BoxedUint::from(Vec::<Limb>::new().into_boxed_slice());
150        assert_eq!(n.as_limbs(), &[Limb::ZERO]);
151
152        let n = BoxedUint::from(vec![Limb(42), Limb::MAX].into_boxed_slice());
153        assert_eq!(n.as_limbs(), &[Limb(42), Limb::MAX]);
154    }
155
156    #[test]
157    fn from_vec() {
158        let n = BoxedUint::from(Vec::<Limb>::new());
159        assert_eq!(n.as_limbs(), &[Limb::ZERO]);
160
161        let n = BoxedUint::from(vec![Limb(42), Limb::MAX]);
162        assert_eq!(n.as_limbs(), &[Limb(42), Limb::MAX]);
163    }
164
165    #[test]
166    fn from_odd_uint() {
167        let odd_u = U256::MAX.to_odd().unwrap();
168        let n = BoxedUint::from(&odd_u);
169        assert_eq!(n.as_limbs(), odd_u.as_ref().as_limbs());
170        let n = BoxedUint::from(odd_u);
171        assert_eq!(n.as_limbs(), odd_u.as_ref().as_limbs());
172        let n = Odd::<BoxedUint>::from(&odd_u);
173        assert_eq!(n.as_ref().as_limbs(), odd_u.as_ref().as_limbs());
174        let n = Odd::<BoxedUint>::from(odd_u);
175        assert_eq!(n.as_ref().as_limbs(), odd_u.as_ref().as_limbs());
176    }
177}