1use std::mem::size_of;
16use std::ops::{Add, AddAssign, Neg};
17
18use super::Group;
19
20macro_rules! decl_int_group {
21 ($t:ty, $t_impl:ident) => {
22 #[derive(Debug, Clone, PartialEq, Eq)]
24 pub struct $t_impl(pub $t);
25
26 impl Add for $t_impl {
27 type Output = Self;
28
29 fn add(self, rhs: Self) -> Self::Output {
30 $t_impl(self.0.wrapping_add(rhs.0))
31 }
32 }
33
34 impl AddAssign for $t_impl {
35 fn add_assign(&mut self, rhs: Self) {
36 self.0 = self.0.wrapping_add(rhs.0);
37 }
38 }
39
40 impl Neg for $t_impl {
41 type Output = Self;
42
43 fn neg(self) -> Self::Output {
44 $t_impl(self.0.wrapping_neg())
45 }
46 }
47
48 impl<const BLEN: usize> Group<BLEN> for $t_impl {
49 fn zero() -> Self {
50 $t_impl(0)
51 }
52 }
53
54 impl<const BLEN: usize> From<[u8; BLEN]> for $t_impl {
55 fn from(value: [u8; BLEN]) -> Self {
56 if cfg!(not(feature = "int-be")) {
57 $t_impl(<$t>::from_le_bytes(
58 (&value[..size_of::<$t>()]).clone().try_into().unwrap(),
59 ))
60 } else {
61 $t_impl(<$t>::from_be_bytes(
62 (&value[..size_of::<$t>()]).clone().try_into().unwrap(),
63 ))
64 }
65 }
66 }
67
68 impl From<$t> for $t_impl {
69 fn from(value: $t) -> Self {
70 $t_impl(value)
71 }
72 }
73
74 impl<const BLEN: usize> From<$t_impl> for [u8; BLEN] {
75 fn from(value: $t_impl) -> Self {
76 let mut bs = [0; BLEN];
77 if cfg!(not(feature = "int-be")) {
78 bs[..size_of::<$t>()].copy_from_slice(&value.0.to_le_bytes());
79 } else {
80 bs[..size_of::<$t>()].copy_from_slice(&value.0.to_be_bytes());
81 }
82 bs
83 }
84 }
85
86 impl From<$t_impl> for $t {
87 fn from(value: $t_impl) -> Self {
88 value.0
89 }
90 }
91 };
92}
93
94decl_int_group!(u8, U8Group);
95decl_int_group!(u16, U16Group);
96decl_int_group!(u32, U32Group);
97decl_int_group!(u64, U64Group);
98decl_int_group!(u128, U128Group);
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use crate::test_group_axioms;
104
105 test_group_axioms!(test_u8_group_axioms, U8Group, 1);
106 test_group_axioms!(test_u16_group_axioms, U16Group, 2);
107 test_group_axioms!(test_u32_group_axioms, U32Group, 4);
108 test_group_axioms!(test_u64_group_axioms, U64Group, 8);
109 test_group_axioms!(test_u128_group_axioms, U128Group, 16);
110}