/ console / network / environment / src / traits / types.rs
types.rs
  1  // Copyright (c) 2025-2026 ACDC Network
  2  // This file is part of the alphavm library.
  3  //
  4  // Alpha Chain | Delta Chain Protocol
  5  // International Monetary Graphite.
  6  //
  7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
  8  // They built world-class ZK infrastructure. We installed the EASY button.
  9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
 10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
 11  //
 12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
 13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
 14  // No rights reserved. No permission required. No warranty. No refunds.
 15  //
 16  // https://creativecommons.org/publicdomain/zero/1.0/
 17  // SPDX-License-Identifier: CC0-1.0
 18  
 19  use crate::prelude::*;
 20  
 21  /// Representation of an address.
 22  pub trait AddressTrait:
 23      Copy
 24      + Clone
 25      + Compare
 26      + Debug
 27      + Deref
 28      + Eq
 29      + Equal
 30      + Parser
 31      + Send
 32      + SizeInBits
 33      + SizeInBytes
 34      + Sync
 35      + TypeName
 36      + Visibility
 37  {
 38  }
 39  
 40  /// Representation of a boolean.
 41  pub trait BooleanTrait:
 42      BitAndAssign
 43      + BitAnd<Self, Output = Self>
 44      + for<'a> BitAnd<&'a Self, Output = Self>
 45      + BitOrAssign
 46      + BitOr<Self, Output = Self>
 47      + for<'a> BitOr<&'a Self, Output = Self>
 48      + BitXorAssign
 49      + BitXor<Self, Output = Self>
 50      + for<'a> BitXor<&'a Self, Output = Self>
 51      + Copy
 52      + Clone
 53      + Debug
 54      + Deref
 55      + Eq
 56      + Equal
 57      + Nand
 58      + Nor
 59      + Not
 60      + Parser
 61      + Send
 62      + SizeInBits
 63      + SizeInDataBits
 64      + SizeInBytes
 65      + Sync
 66      + TypeName
 67      + Uniform
 68  {
 69  }
 70  
 71  /// Representation of a base field element.
 72  pub trait FieldTrait:
 73      'static
 74      + Add<Self, Output = Self>
 75      + for<'a> Add<&'a Self, Output = Self>
 76      + AddAssign<Self>
 77      + for<'a> AddAssign<&'a Self>
 78      + Clone
 79      + Copy
 80      + Compare
 81      + Debug
 82      + Deref
 83      + Div<Self, Output = Self>
 84      + for<'a> Div<&'a Self, Output = Self>
 85      + DivAssign<Self>
 86      + for<'a> DivAssign<&'a Self>
 87      + Double<Output = Self>
 88      + Eq
 89      + Equal
 90      + FromBytes
 91      + core::hash::Hash
 92      + Inverse<Output = Self>
 93      + Mul<Self, Output = Self>
 94      + for<'a> Mul<&'a Self, Output = Self>
 95      + MulAssign<Self>
 96      + for<'a> MulAssign<&'a Self>
 97      + Neg<Output = Self>
 98      + One
 99      + Ord
100      + Parser
101      + Pow<Self, Output = Self>
102      + for<'a> Pow<&'a Self, Output = Self>
103      + Product<Self>
104      + for<'a> Product<&'a Self>
105      + Send
106      + SizeInBits
107      + SizeInDataBits
108      + SizeInBytes
109      + Sync
110      + Square<Output = Self>
111      + SquareRoot<Output = Self>
112      + Sub<Self, Output = Self>
113      + for<'a> Sub<&'a Self, Output = Self>
114      + SubAssign<Self>
115      + for<'a> SubAssign<&'a Self>
116      + Sum<Self>
117      + for<'a> Sum<&'a Self>
118      + ToBytes
119      + TypeName
120      + Uniform
121      + Zero
122  {
123  }
124  
125  /// Representation of a group element.
126  pub trait GroupTrait<S: ScalarTrait>:
127      'static
128      + Add<Self, Output = Self>
129      + for<'a> Add<&'a Self, Output = Self>
130      + AddAssign<Self>
131      + for<'a> AddAssign<&'a Self>
132      + Clone
133      + Copy
134      + Debug
135      + Double<Output = Self>
136      + Eq
137      + Equal
138      + Mul<S>
139      + for<'a> Mul<&'a S>
140      + MulAssign<S>
141      + for<'a> MulAssign<&'a S>
142      + Neg<Output = Self>
143      + Parser
144      + Send
145      + SizeInBits
146      + SizeInBytes
147      + Sync
148      + Sub<Self, Output = Self>
149      + for<'a> Sub<&'a Self, Output = Self>
150      + SubAssign<Self>
151      + for<'a> SubAssign<&'a Self>
152      + Sum<Self>
153      + for<'a> Sum<&'a Self>
154      + TypeName
155      + Uniform
156      + Visibility
157      + Zero
158  {
159  }
160  
161  /// Representation of a scalar field element.
162  pub trait ScalarTrait:
163      'static
164      + Add<Self, Output = Self>
165      + for<'a> Add<&'a Self, Output = Self>
166      + AddAssign<Self>
167      + for<'a> AddAssign<&'a Self>
168      + Clone
169      + Copy
170      + Compare
171      + Debug
172      + Deref
173      + Div<Self, Output = Self>
174      + for<'a> Div<&'a Self, Output = Self>
175      + DivAssign<Self>
176      + for<'a> DivAssign<&'a Self>
177      + Double<Output = Self>
178      + Eq
179      + Equal
180      + Inverse<Output = Self>
181      + Mul<Self, Output = Self>
182      + for<'a> Mul<&'a Self, Output = Self>
183      + MulAssign<Self>
184      + for<'a> MulAssign<&'a Self>
185      + Neg<Output = Self>
186      + One
187      + Parser
188      + Pow<Self, Output = Self>
189      + for<'a> Pow<&'a Self, Output = Self>
190      + Product<Self>
191      + for<'a> Product<&'a Self>
192      + Send
193      + SizeInBits
194      + SizeInDataBits
195      + SizeInBytes
196      + Sync
197      + Square<Output = Self>
198      + Sub<Self, Output = Self>
199      + for<'a> Sub<&'a Self, Output = Self>
200      + SubAssign<Self>
201      + for<'a> SubAssign<&'a Self>
202      + Sum<Self>
203      + for<'a> Sum<&'a Self>
204      + TypeName
205      + Uniform
206      + Zero
207  {
208  }
209  
210  /// Representation of a string.
211  pub trait StringTrait:
212      Clone + Debug + Display + Eq + Equal + FromBytes + Parser + Send + Sync + ToBytes + TypeName + Uniform
213  {
214  }
215  
216  /// Representation of an integer.
217  pub trait IntegerTrait<I: integer_type::IntegerType, U8: IntegerCore<u8>, U16: IntegerCore<u16>, U32: IntegerCore<u32>>:
218      IntegerCore<I>
219      + Pow<U8, Output = Self>
220      + Shl<U8, Output = Self>
221      + for<'a> Shl<&'a U8, Output = Self>
222      + ShlChecked<U8, Output = Self>
223      + ShlWrapped<U8, Output = Self>
224      + ShlAssign<U8>
225      + Shr<U8, Output = Self>
226      + for<'a> Shr<&'a U8, Output = Self>
227      + ShrChecked<U8, Output = Self>
228      + ShrWrapped<U8, Output = Self>
229      + ShrAssign<U8>
230      + Pow<U16, Output = Self>
231      + Shl<U16, Output = Self>
232      + for<'a> Shl<&'a U16, Output = Self>
233      + ShlChecked<U16, Output = Self>
234      + ShlWrapped<U16, Output = Self>
235      + ShlAssign<U16>
236      + Shr<U16, Output = Self>
237      + for<'a> Shr<&'a U16, Output = Self>
238      + ShrChecked<U16, Output = Self>
239      + ShrWrapped<U16, Output = Self>
240      + ShrAssign<U16>
241      + Pow<U32, Output = Self>
242      + Shl<U32, Output = Self>
243      + for<'a> Shl<&'a U32, Output = Self>
244      + ShlChecked<U32, Output = Self>
245      + ShlWrapped<U32, Output = Self>
246      + ShlAssign<U32>
247      + Shr<U32, Output = Self>
248      + for<'a> Shr<&'a U32, Output = Self>
249      + ShrChecked<U32, Output = Self>
250      + ShrWrapped<U32, Output = Self>
251      + ShrAssign<U32>
252  {
253  }
254  
255  pub trait IntegerCore<I: integer_type::IntegerType>:
256      'static
257      + Add<Self, Output = Self>
258      + for<'a> Add<&'a Self, Output = Self>
259      + AddAssign<Self>
260      + for<'a> AddAssign<&'a Self>
261      + BitAndAssign
262      + BitAnd<Self, Output = Self>
263      + for<'a> BitAnd<&'a Self, Output = Self>
264      + BitOrAssign
265      + BitOr<Self, Output = Self>
266      + for<'a> BitOr<&'a Self, Output = Self>
267      + BitXorAssign
268      + BitXor<Self, Output = Self>
269      + for<'a> BitXor<&'a Self, Output = Self>
270      + Copy
271      + Clone
272      + Compare
273      + Debug
274      + Deref
275      + Div<Self, Output = Self>
276      + for<'a> Div<&'a Self, Output = Self>
277      + DivAssign<Self>
278      + for<'a> DivAssign<&'a Self>
279      + Eq
280      + Equal
281      + Modulo
282      + Mul<Self, Output = Self>
283      + for<'a> Mul<&'a Self, Output = Self>
284      + MulAssign<Self>
285      + for<'a> MulAssign<&'a Self>
286      + Neg<Output = Self>
287      + Not<Output = Self>
288      + One
289      + Parser
290      + Rem<Self, Output = Self>
291      + for<'a> Rem<&'a Self, Output = Self>
292      + RemAssign<Self>
293      + for<'a> RemAssign<&'a Self>
294      + Send
295      + SizeInBits
296      + SizeInBytes
297      + Sync
298      + Sub<Self, Output = Self>
299      + for<'a> Sub<&'a Self, Output = Self>
300      + SubAssign<Self>
301      + for<'a> SubAssign<&'a Self>
302      + TypeName
303      + Uniform
304      + Visibility
305      + Zero
306  {
307  }
308  
309  pub mod integer_type {
310      use alphavm_utilities::{FromBits, FromBytes, ToBits, ToBytes, Uniform};
311  
312      use core::{
313          fmt::{Debug, Display},
314          hash::Hash,
315          num::ParseIntError,
316          ops::{Div, Rem},
317          str::FromStr,
318      };
319      use num_traits::{
320          CheckedNeg,
321          CheckedRem,
322          CheckedShr,
323          One as NumOne,
324          PrimInt,
325          ToPrimitive,
326          WrappingAdd,
327          WrappingMul,
328          WrappingNeg,
329          WrappingShl,
330          WrappingShr,
331          WrappingSub,
332          Zero as NumZero,
333      };
334  
335      /// Trait bound for integer values. Common to both signed and unsigned integers.
336      pub trait IntegerType:
337          'static
338          + CheckedAbs
339          + CheckedNeg
340          + CheckedPow
341          + CheckedRem
342          + CheckedShl
343          + CheckedShr
344          + Debug
345          + Default
346          + Display
347          + FromBits
348          + FromBytes
349          + FromStr<Err = ParseIntError>
350          + Hash
351          + Modulo
352          + NumZero
353          + NumOne
354          + PartialOrd
355          + Send
356          + Sync
357          + ToBits
358          + ToBytes
359          + ToPrimitive
360          + Uniform
361          + WrappingAbs
362          + WrappingAdd
363          + WrappingMul
364          + WrappingNeg
365          + WrappingPow
366          + WrappingRem
367          + WrappingShl
368          + WrappingShr
369          + WrappingSub
370          + WrappingDiv
371          + IntegerProperties
372      {
373      }
374  
375      impl IntegerType for i8 {}
376      impl IntegerType for i16 {}
377      impl IntegerType for i32 {}
378      impl IntegerType for i64 {}
379      impl IntegerType for i128 {}
380  
381      impl IntegerType for u8 {}
382      impl IntegerType for u16 {}
383      impl IntegerType for u32 {}
384      impl IntegerType for u64 {}
385      impl IntegerType for u128 {}
386  
387      macro_rules! binary_impl {
388          ($trait_name:ident, $t:ty, $method:ident, $arg1: ident, $argname:ident, $arg2: ident, $rt:ty, $body:expr) => {
389              impl $trait_name for $t {
390                  #[inline]
391                  fn $method(&$arg1, $argname: &$arg2) -> $rt {
392                      $body
393                  }
394              }
395          };
396      }
397  
398      pub trait CheckedPow: Sized {
399          fn checked_pow(&self, v: &u32) -> Option<Self>;
400      }
401  
402      binary_impl!(CheckedPow, u8, checked_pow, self, v, u32, Option<u8>, u8::checked_pow(*self, *v));
403      binary_impl!(CheckedPow, u16, checked_pow, self, v, u32, Option<u16>, u16::checked_pow(*self, *v));
404      binary_impl!(CheckedPow, u32, checked_pow, self, v, u32, Option<u32>, u32::checked_pow(*self, *v));
405      binary_impl!(CheckedPow, u64, checked_pow, self, v, u32, Option<u64>, u64::checked_pow(*self, *v));
406      binary_impl!(CheckedPow, u128, checked_pow, self, v, u32, Option<u128>, u128::checked_pow(*self, *v));
407      binary_impl!(CheckedPow, i8, checked_pow, self, v, u32, Option<i8>, i8::checked_pow(*self, *v));
408      binary_impl!(CheckedPow, i16, checked_pow, self, v, u32, Option<i16>, i16::checked_pow(*self, *v));
409      binary_impl!(CheckedPow, i32, checked_pow, self, v, u32, Option<i32>, i32::checked_pow(*self, *v));
410      binary_impl!(CheckedPow, i64, checked_pow, self, v, u32, Option<i64>, i64::checked_pow(*self, *v));
411      binary_impl!(CheckedPow, i128, checked_pow, self, v, u32, Option<i128>, i128::checked_pow(*self, *v));
412  
413      pub trait CheckedShl: Sized {
414          fn checked_shl(&self, v: &u32) -> Option<Self>;
415      }
416  
417      #[rustfmt::skip]
418      binary_impl!(CheckedShl, u8, checked_shl, self, v, u32, Option<u8>, u8::checked_pow(2u8, *v).and_then(|x| u8::checked_mul(*self, x)));
419      #[rustfmt::skip]
420      binary_impl!(CheckedShl, u16, checked_shl, self, v, u32, Option<u16>, u16::checked_pow(2u16, *v).and_then(|x| u16::checked_mul(*self, x)));
421      #[rustfmt::skip]
422      binary_impl!(CheckedShl, u32, checked_shl, self, v, u32, Option<u32>, u32::checked_pow(2u32, *v).and_then(|x| u32::checked_mul(*self, x)));
423      #[rustfmt::skip]
424      binary_impl!(CheckedShl, u64, checked_shl, self, v, u32, Option<u64>, u64::checked_pow(2u64, *v).and_then(|x| u64::checked_mul(*self, x)));
425      #[rustfmt::skip]
426      binary_impl!(CheckedShl, u128, checked_shl, self, v, u32, Option<u128>, u128::checked_pow(2u128, *v).and_then(|x| u128::checked_mul(*self, x)));
427      #[rustfmt::skip]
428      binary_impl!(CheckedShl, i8, checked_shl, self, v, u32, Option<i8>, u8::checked_pow(2u8, *v).and_then(|x| i8::checked_mul(if (x as i8) == i8::MIN { self.wrapping_neg() } else { *self }, x as i8)));
429      #[rustfmt::skip]
430      binary_impl!(CheckedShl, i16, checked_shl, self, v, u32, Option<i16>, u16::checked_pow(2u16, *v).and_then(|x| i16::checked_mul(if (x as i16) == i16::MIN { self.wrapping_neg() } else { *self }, x as i16)));
431      #[rustfmt::skip]
432      binary_impl!(CheckedShl, i32, checked_shl, self, v, u32, Option<i32>, u32::checked_pow(2u32, *v).and_then(|x| i32::checked_mul(if (x as i32) == i32::MIN { self.wrapping_neg() } else { *self }, x as i32)));
433      #[rustfmt::skip]
434      binary_impl!(CheckedShl, i64, checked_shl, self, v, u32, Option<i64>, u64::checked_pow(2u64, *v).and_then(|x| i64::checked_mul(if (x as i64) == i64::MIN { self.wrapping_neg() } else { *self }, x as i64)));
435      #[rustfmt::skip]
436      binary_impl!(CheckedShl, i128, checked_shl, self, v, u32, Option<i128>, u128::checked_pow(2u128, *v).and_then(|x| i128::checked_mul(if (x as i128) == i128::MIN { self.wrapping_neg() } else { *self }, x as i128)));
437  
438      pub trait Modulo: Sized + Rem<Self, Output = Self> {
439          fn modulo(&self, v: &Self) -> Self;
440      }
441  
442      binary_impl!(Modulo, u8, modulo, self, v, Self, u8, u8::wrapping_rem(*self, *v));
443      binary_impl!(Modulo, u16, modulo, self, v, Self, u16, u16::wrapping_rem(*self, *v));
444      binary_impl!(Modulo, u32, modulo, self, v, Self, u32, u32::wrapping_rem(*self, *v));
445      binary_impl!(Modulo, u64, modulo, self, v, Self, u64, u64::wrapping_rem(*self, *v));
446      binary_impl!(Modulo, u128, modulo, self, v, Self, u128, u128::wrapping_rem(*self, *v));
447      #[rustfmt::skip]
448      binary_impl!(Modulo, i8, modulo, self, _v, Self, i8, panic!("modulo is not implemented for i8"));
449      #[rustfmt::skip]
450      binary_impl!(Modulo, i16, modulo, self, _v, Self, i16, panic!("modulo is not implemented for i16"));
451      #[rustfmt::skip]
452      binary_impl!(Modulo, i32, modulo, self, _v, Self, i32, panic!("modulo is not implemented for i32"));
453      #[rustfmt::skip]
454      binary_impl!(Modulo, i64, modulo, self, _v, Self, i64, panic!("modulo is not implemented for i64"));
455      #[rustfmt::skip]
456      binary_impl!(Modulo, i128, modulo, self, _v, Self, i128, panic!("modulo is not implemented for i128"));
457  
458      pub trait WrappingDiv: Sized + Div<Self, Output = Self> {
459          fn wrapping_div(&self, v: &Self) -> Self;
460      }
461  
462      binary_impl!(WrappingDiv, u8, wrapping_div, self, v, Self, u8, u8::wrapping_div(*self, *v));
463      binary_impl!(WrappingDiv, u16, wrapping_div, self, v, Self, u16, u16::wrapping_div(*self, *v));
464      binary_impl!(WrappingDiv, u32, wrapping_div, self, v, Self, u32, u32::wrapping_div(*self, *v));
465      binary_impl!(WrappingDiv, u64, wrapping_div, self, v, Self, u64, u64::wrapping_div(*self, *v));
466      binary_impl!(WrappingDiv, u128, wrapping_div, self, v, Self, u128, u128::wrapping_div(*self, *v));
467      binary_impl!(WrappingDiv, i8, wrapping_div, self, v, Self, i8, i8::wrapping_div(*self, *v));
468      binary_impl!(WrappingDiv, i16, wrapping_div, self, v, Self, i16, i16::wrapping_div(*self, *v));
469      binary_impl!(WrappingDiv, i32, wrapping_div, self, v, Self, i32, i32::wrapping_div(*self, *v));
470      binary_impl!(WrappingDiv, i64, wrapping_div, self, v, Self, i64, i64::wrapping_div(*self, *v));
471      binary_impl!(WrappingDiv, i128, wrapping_div, self, v, Self, i128, i128::wrapping_div(*self, *v));
472  
473      pub trait WrappingRem: Sized + Rem<Self, Output = Self> {
474          fn wrapping_rem(&self, v: &Self) -> Self;
475      }
476  
477      binary_impl!(WrappingRem, u8, wrapping_rem, self, v, Self, u8, u8::wrapping_rem(*self, *v));
478      binary_impl!(WrappingRem, u16, wrapping_rem, self, v, Self, u16, u16::wrapping_rem(*self, *v));
479      binary_impl!(WrappingRem, u32, wrapping_rem, self, v, Self, u32, u32::wrapping_rem(*self, *v));
480      binary_impl!(WrappingRem, u64, wrapping_rem, self, v, Self, u64, u64::wrapping_rem(*self, *v));
481      binary_impl!(WrappingRem, u128, wrapping_rem, self, v, Self, u128, u128::wrapping_rem(*self, *v));
482      binary_impl!(WrappingRem, i8, wrapping_rem, self, v, Self, i8, i8::wrapping_rem(*self, *v));
483      binary_impl!(WrappingRem, i16, wrapping_rem, self, v, Self, i16, i16::wrapping_rem(*self, *v));
484      binary_impl!(WrappingRem, i32, wrapping_rem, self, v, Self, i32, i32::wrapping_rem(*self, *v));
485      binary_impl!(WrappingRem, i64, wrapping_rem, self, v, Self, i64, i64::wrapping_rem(*self, *v));
486      binary_impl!(WrappingRem, i128, wrapping_rem, self, v, Self, i128, i128::wrapping_rem(*self, *v));
487  
488      pub trait WrappingPow: Sized {
489          fn wrapping_pow(&self, v: &u32) -> Self;
490      }
491  
492      binary_impl!(WrappingPow, u8, wrapping_pow, self, v, u32, u8, u8::wrapping_pow(*self, *v));
493      binary_impl!(WrappingPow, u16, wrapping_pow, self, v, u32, u16, u16::wrapping_pow(*self, *v));
494      binary_impl!(WrappingPow, u32, wrapping_pow, self, v, u32, u32, u32::wrapping_pow(*self, *v));
495      binary_impl!(WrappingPow, u64, wrapping_pow, self, v, u32, u64, u64::wrapping_pow(*self, *v));
496      binary_impl!(WrappingPow, u128, wrapping_pow, self, v, u32, u128, u128::wrapping_pow(*self, *v));
497      binary_impl!(WrappingPow, i8, wrapping_pow, self, v, u32, i8, i8::wrapping_pow(*self, *v));
498      binary_impl!(WrappingPow, i16, wrapping_pow, self, v, u32, i16, i16::wrapping_pow(*self, *v));
499      binary_impl!(WrappingPow, i32, wrapping_pow, self, v, u32, i32, i32::wrapping_pow(*self, *v));
500      binary_impl!(WrappingPow, i64, wrapping_pow, self, v, u32, i64, i64::wrapping_pow(*self, *v));
501      binary_impl!(WrappingPow, i128, wrapping_pow, self, v, u32, i128, i128::wrapping_pow(*self, *v));
502  
503      macro_rules! unary_impl {
504          ($trait_name:ident, $t:ty, $method:ident, $arg: ident, $rt:ty, $body:expr) => {
505              impl $trait_name for $t {
506                  #[inline]
507                  fn $method(&$arg) -> $rt {
508                      $body
509                  }
510              }
511          };
512      }
513  
514      pub trait CheckedAbs: Sized {
515          fn checked_abs(&self) -> Option<Self>;
516      }
517  
518      unary_impl!(CheckedAbs, u8, checked_abs, self, Option<u8>, Some(*self));
519      unary_impl!(CheckedAbs, u16, checked_abs, self, Option<u16>, Some(*self));
520      unary_impl!(CheckedAbs, u32, checked_abs, self, Option<u32>, Some(*self));
521      unary_impl!(CheckedAbs, u64, checked_abs, self, Option<u64>, Some(*self));
522      unary_impl!(CheckedAbs, u128, checked_abs, self, Option<u128>, Some(*self));
523      unary_impl!(CheckedAbs, i8, checked_abs, self, Option<i8>, i8::checked_abs(*self));
524      unary_impl!(CheckedAbs, i16, checked_abs, self, Option<i16>, i16::checked_abs(*self));
525      unary_impl!(CheckedAbs, i32, checked_abs, self, Option<i32>, i32::checked_abs(*self));
526      unary_impl!(CheckedAbs, i64, checked_abs, self, Option<i64>, i64::checked_abs(*self));
527      unary_impl!(CheckedAbs, i128, checked_abs, self, Option<i128>, i128::checked_abs(*self));
528  
529      pub trait WrappingAbs: Sized {
530          fn wrapping_abs(&self) -> Self;
531      }
532  
533      unary_impl!(WrappingAbs, u8, wrapping_abs, self, u8, *self);
534      unary_impl!(WrappingAbs, u16, wrapping_abs, self, u16, *self);
535      unary_impl!(WrappingAbs, u32, wrapping_abs, self, u32, *self);
536      unary_impl!(WrappingAbs, u64, wrapping_abs, self, u64, *self);
537      unary_impl!(WrappingAbs, u128, wrapping_abs, self, u128, *self);
538      unary_impl!(WrappingAbs, i8, wrapping_abs, self, i8, i8::wrapping_abs(*self));
539      unary_impl!(WrappingAbs, i16, wrapping_abs, self, i16, i16::wrapping_abs(*self));
540      unary_impl!(WrappingAbs, i32, wrapping_abs, self, i32, i32::wrapping_abs(*self));
541      unary_impl!(WrappingAbs, i64, wrapping_abs, self, i64, i64::wrapping_abs(*self));
542      unary_impl!(WrappingAbs, i128, wrapping_abs, self, i128, i128::wrapping_abs(*self));
543  
544      /// Properties common to all integer types.
545      pub trait IntegerProperties: PrimInt + Debug + Display {
546          type Dual: IntegerType;
547          /// Returns the number of bits required to represent this integer.
548          const BITS: u64;
549          /// Returns the maximum value representable by this integer.
550          const MAX: Self;
551          /// Returns the minimum value representable by this integer.
552          const MIN: Self;
553  
554          /// Returns `true` if `Self` is a signed integer and `false` otherwise.
555          fn is_signed() -> bool;
556  
557          /// Returns the name of the integer type as a string slice. (i.e. "u8")
558          fn type_name() -> &'static str;
559  
560          /// Casts `self` into its dual.
561          fn into_dual(self) -> Self::Dual;
562      }
563  
564      macro_rules! integer_properties_impl {
565          ($t:ty, $dual:ty, $is_signed:expr) => {
566              impl IntegerProperties for $t {
567                  type Dual = $dual;
568  
569                  const BITS: u64 = <$t>::BITS as u64;
570                  const MAX: $t = <$t>::MAX;
571                  const MIN: $t = <$t>::MIN;
572  
573                  #[inline]
574                  fn is_signed() -> bool {
575                      $is_signed
576                  }
577  
578                  #[inline]
579                  fn type_name() -> &'static str {
580                      std::any::type_name::<$t>()
581                  }
582  
583                  #[inline]
584                  fn into_dual(self) -> Self::Dual {
585                      self as $dual
586                  }
587              }
588          };
589      }
590  
591      integer_properties_impl!(u8, i8, false);
592      integer_properties_impl!(u16, i16, false);
593      integer_properties_impl!(u32, i32, false);
594      integer_properties_impl!(u64, i64, false);
595      integer_properties_impl!(u128, i128, false);
596      integer_properties_impl!(i8, u8, true);
597      integer_properties_impl!(i16, u16, true);
598      integer_properties_impl!(i32, u32, true);
599      integer_properties_impl!(i64, u64, true);
600      integer_properties_impl!(i128, u128, true);
601  }
602  
603  /// Trait pattern to prevent abuse of Magnitude.
604  pub mod integer_magnitude {
605      use super::integer_type::IntegerType;
606      use num_traits::{ToPrimitive, Unsigned};
607  
608      /// Trait for integers that can be used as an unsigned magnitude.
609      /// `Magnitude`s are either used to represent an integer exponent
610      /// or the right operand in integer shift operations.
611      pub trait Magnitude: IntegerType + ToPrimitive + Unsigned {}
612      impl Magnitude for u8 {}
613      impl Magnitude for u16 {}
614      impl Magnitude for u32 {}
615  }