1use std::mem::size_of;
8use std::ops::{Add, AddAssign};
9
10use crate::Group;
11
12macro_rules! decl_int_group {
13 ($t:ty, $t_impl:ident) => {
14 #[derive(Debug, Clone, PartialEq, Eq)]
16 pub struct $t_impl(pub $t);
17
18 impl Add for $t_impl {
19 type Output = Self;
20
21 fn add(self, rhs: Self) -> Self::Output {
22 $t_impl(self.0.wrapping_add(rhs.0))
23 }
24 }
25
26 impl AddAssign for $t_impl {
27 fn add_assign(&mut self, rhs: Self) {
28 self.0 = self.0.wrapping_add(rhs.0);
29 }
30 }
31
32 impl<const LAMBDA: usize> Group<LAMBDA> for $t_impl {
33 fn zero() -> Self {
34 $t_impl(0)
35 }
36
37 fn add_inverse(self) -> Self {
38 $t_impl(self.0.wrapping_neg())
39 }
40 }
41
42 impl<const LAMBDA: usize> From<[u8; LAMBDA]> for $t_impl {
43 fn from(value: [u8; LAMBDA]) -> Self {
44 if cfg!(not(feature = "int-be")) {
45 $t_impl(<$t>::from_le_bytes(
46 (&value[..size_of::<$t>()]).clone().try_into().unwrap(),
47 ))
48 } else {
49 $t_impl(<$t>::from_be_bytes(
50 (&value[..size_of::<$t>()]).clone().try_into().unwrap(),
51 ))
52 }
53 }
54 }
55
56 impl<const LAMBDA: usize> From<$t_impl> for [u8; LAMBDA] {
57 fn from(value: $t_impl) -> Self {
58 let mut bs = [0; LAMBDA];
59 if cfg!(not(feature = "int-be")) {
60 bs[..size_of::<$t>()].copy_from_slice(&value.0.to_le_bytes());
61 } else {
62 bs[..size_of::<$t>()].copy_from_slice(&value.0.to_be_bytes());
63 }
64 bs
65 }
66 }
67 };
68}
69
70decl_int_group!(u8, U8Group);
71decl_int_group!(u16, U16Group);
72decl_int_group!(u32, U32Group);
73decl_int_group!(u64, U64Group);
74decl_int_group!(u128, U128Group);
75decl_int_group!(usize, UsizeGroup);
76
77decl_int_group!(i8, I8Group);
78decl_int_group!(i16, I16Group);
79decl_int_group!(i32, I32Group);
80decl_int_group!(i64, I64Group);
81decl_int_group!(i128, I128Group);
82decl_int_group!(isize, IsizeGroup);