Skip to main content

zinc_utils/
from_ref.rs

1use crypto_primitives::{
2    Wrapper, boolean::Boolean, crypto_bigint_int::Int, crypto_bigint_uint::Uint,
3};
4
5//
6// FromRef
7//
8
9/// This trait is essentially equivalent to `From<&T>`, other than it allows us
10/// to implement it for external types that don't implement it out of the box,
11/// most notably primitive types.
12pub trait FromRef<T> {
13    fn from_ref(value: &T) -> Self;
14}
15
16impl<T> FromRef<Boolean> for T
17where
18    T: From<bool>,
19{
20    fn from_ref(value: &Boolean) -> Self {
21        T::from(**value)
22    }
23}
24
25macro_rules! impl_from_ref_for_primitive {
26    ($dst:ty, [$($src:ty),+]) => {
27        $(
28            impl FromRef<$src> for $dst {
29                fn from_ref(value: &$src) -> Self {
30                    <$dst>::from(*value)
31                }
32            }
33        )+
34    };
35}
36
37impl_from_ref_for_primitive!(i128, [i128, i64, i32, i16, i8]);
38impl_from_ref_for_primitive!(i64, [i64, i32, i16, i8]);
39impl_from_ref_for_primitive!(i32, [i32, i16, i8]);
40impl_from_ref_for_primitive!(i16, [i16, i8]);
41impl_from_ref_for_primitive!(i8, [i8]);
42
43macro_rules! impl_int_from_primitive_ref {
44    ($($t:ty),+) => {
45        $(
46            impl<const LIMBS: usize> FromRef<$t> for Int<LIMBS> {
47                #[inline(always)]
48                fn from_ref(value: &$t) -> Self {
49                    Self::from(*value)
50                }
51            }
52        )+
53    };
54}
55
56impl_int_from_primitive_ref!(i8, i16, i32, i64, i128);
57
58macro_rules! impl_uint_from_primitive_ref {
59    ($($t:ty),+) => {
60        $(
61            impl<const LIMBS: usize> FromRef<$t> for Uint<LIMBS> {
62                #[inline(always)]
63                fn from_ref(value: &$t) -> Self {
64                    Self::from(*value)
65                }
66            }
67        )+
68    };
69}
70
71impl_uint_from_primitive_ref!(u8, u16, u32, u64, u128);
72
73impl<const LIMBS: usize, const LIMBS2: usize> FromRef<Int<LIMBS2>> for Int<LIMBS> {
74    #[inline]
75    fn from_ref(value: &Int<LIMBS2>) -> Self {
76        Self::try_from(value.inner()).expect("Destination Int type is too small")
77    }
78}
79
80impl<const LIMBS: usize, const LIMBS2: usize> FromRef<Uint<LIMBS2>> for Uint<LIMBS> {
81    #[inline]
82    fn from_ref(value: &Uint<LIMBS2>) -> Self {
83        Self::try_from(value.inner()).expect("Destination Uint type is too small")
84    }
85}