1use crate::U256;
22use core::{
23 cmp::Ordering,
24 fmt,
25 hash::{Hash, Hasher},
26 mem::transmute,
27 num::NonZero,
28};
29#[cfg(feature = "codec")]
30use scale_info::{
31 TypeInfo,
32 prelude::vec::Vec,
33 scale::{Decode, Encode, EncodeLike, Error, Input, Output},
34};
35
36#[derive(Clone, Copy)]
38#[cfg_attr(feature = "codec", derive(TypeInfo))]
39#[repr(transparent)]
40pub struct NonZeroU256(U256);
41
42macro_rules! impl_nonzero_fmt {
43 ($Trait:ident) => {
44 impl fmt::$Trait for NonZeroU256 {
45 #[inline]
46 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47 self.get().fmt(f)
48 }
49 }
50 };
51}
52
53impl_nonzero_fmt!(Debug);
54impl_nonzero_fmt!(Display);
55impl_nonzero_fmt!(LowerHex);
56impl_nonzero_fmt!(UpperHex);
57
58impl PartialEq for NonZeroU256 {
59 #[inline]
60 fn eq(&self, other: &Self) -> bool {
61 self.get() == other.get()
62 }
63}
64
65impl Eq for NonZeroU256 {}
66
67impl PartialOrd for NonZeroU256 {
68 #[inline]
69 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
70 Some(self.cmp(other))
71 }
72
73 #[inline]
74 fn lt(&self, other: &Self) -> bool {
75 self.get() < other.get()
76 }
77
78 #[inline]
79 fn le(&self, other: &Self) -> bool {
80 self.get() <= other.get()
81 }
82
83 #[inline]
84 fn gt(&self, other: &Self) -> bool {
85 self.get() > other.get()
86 }
87
88 #[inline]
89 fn ge(&self, other: &Self) -> bool {
90 self.get() >= other.get()
91 }
92}
93
94impl Ord for NonZeroU256 {
95 #[inline]
96 fn cmp(&self, other: &Self) -> Ordering {
97 self.get().cmp(&other.get())
98 }
99
100 #[inline]
101 fn max(self, other: Self) -> Self {
102 Self(self.get().max(other.get()))
104 }
105
106 #[inline]
107 fn min(self, other: Self) -> Self {
108 Self(self.get().min(other.get()))
110 }
111
112 #[inline]
113 fn clamp(self, min: Self, max: Self) -> Self {
114 Self(self.get().clamp(min.get(), max.get()))
116 }
117}
118
119impl Hash for NonZeroU256 {
120 #[inline]
121 fn hash<H>(&self, state: &mut H)
122 where
123 H: Hasher,
124 {
125 self.get().hash(state)
126 }
127}
128
129impl AsRef<[u64]> for NonZeroU256 {
131 #[inline]
132 fn as_ref(&self) -> &[u64] {
133 self.0.as_ref()
134 }
135}
136
137impl<'a> From<&'a NonZeroU256> for NonZeroU256 {
138 fn from(x: &'a NonZeroU256) -> NonZeroU256 {
139 *x
140 }
141}
142
143impl NonZeroU256 {
144 pub const MIN: NonZeroU256 = unsafe { NonZeroU256::new_unchecked(U256::one()) };
146 pub const MAX: NonZeroU256 = unsafe { NonZeroU256::new_unchecked(U256::MAX) };
148
149 #[must_use]
151 #[inline]
152 pub const fn new(n: U256) -> Option<Self> {
153 if n.is_zero() { None } else { Some(Self(n)) }
154 }
155
156 #[must_use]
163 #[inline]
164 pub const unsafe fn new_unchecked(n: U256) -> Self {
165 unsafe { transmute(n) }
167 }
168
169 #[inline]
171 pub const fn get(self) -> U256 {
172 match Self::new(self.0) {
180 Some(Self(n)) => n,
181 None => {
182 unreachable!()
184 }
185 }
186 }
187
188 #[inline]
192 pub fn checked_add(self, other: U256) -> Option<Self> {
193 self.get()
201 .checked_add(other)
202 .map(|result| unsafe { Self::new_unchecked(result) })
203 }
204
205 #[inline]
207 pub fn saturating_add(self, other: U256) -> Self {
208 unsafe { Self::new_unchecked(self.get().saturating_add(other)) }
216 }
217
218 #[inline(always)]
220 pub fn overflowing_add(self, other: U256) -> (Self, bool) {
221 let result = self.get().overflowing_add(other);
222 if result.0.is_zero() {
223 (Self::MIN, true)
224 } else {
225 unsafe { (Self::new_unchecked(result.0), result.1) }
226 }
227 }
228
229 pub fn checked_sub(self, other: U256) -> Option<Self> {
231 match self.get().overflowing_sub(other) {
232 (_, true) => None,
233 (val, _) => Self::new(val),
234 }
235 }
236
237 pub fn saturating_sub(self, other: U256) -> Self {
239 match self.get().overflowing_sub(other) {
240 (_, true) => Self::MIN,
241 (val, false) => Self::new(val).unwrap_or(Self::MIN),
242 }
243 }
244
245 #[inline(always)]
247 pub fn overflowing_sub(self, other: U256) -> (Self, bool) {
248 let result = self.get().overflowing_sub(other);
249 if result.0.is_zero() {
250 (Self::MAX, true)
251 } else {
252 unsafe { (Self::new_unchecked(result.0), result.1) }
253 }
254 }
255
256 #[inline]
260 pub fn checked_mul(self, other: Self) -> Option<Self> {
261 self.get()
269 .checked_mul(other.get())
270 .map(|result| unsafe { Self::new_unchecked(result) })
271 }
272
273 #[inline]
275 pub fn saturating_mul(self, other: Self) -> Self {
276 unsafe { Self::new_unchecked(self.get().saturating_mul(other.get())) }
285 }
286
287 #[inline(always)]
289 pub fn overflowing_mul(self, other: Self) -> (Self, bool) {
290 let result = self.get().overflowing_mul(other.get());
291 if result.0.is_zero() {
292 (Self::MAX, true)
293 } else {
294 unsafe { (Self::new_unchecked(result.0), result.1) }
295 }
296 }
297
298 #[inline]
302 pub fn checked_pow(self, other: U256) -> Option<Self> {
303 self.get()
311 .checked_pow(other)
312 .map(|result| unsafe { Self::new_unchecked(result) })
313 }
314
315 #[inline]
317 pub fn overflowing_pow(self, other: U256) -> (Self, bool) {
318 let result = self.get().overflowing_pow(other);
319 if result.0.is_zero() {
320 (Self::MAX, true)
321 } else {
322 unsafe { (Self::new_unchecked(result.0), result.1) }
323 }
324 }
325
326 #[inline]
333 pub fn pow(self, other: U256) -> Self {
334 unsafe { Self::new_unchecked(self.get().pow(other)) }
342 }
343}
344
345impl From<NonZeroU256> for U256 {
346 #[inline]
347 fn from(nonzero: NonZeroU256) -> Self {
348 nonzero.get()
350 }
351}
352
353macro_rules! impl_map_from {
354 ($from:ty) => {
355 impl From<$from> for NonZeroU256 {
356 fn from(value: $from) -> Self {
357 unsafe { Self::new_unchecked(U256::from(value.get())) }
358 }
359 }
360 };
361}
362
363impl_map_from!(NonZero<u8>);
364impl_map_from!(NonZero<u16>);
365impl_map_from!(NonZero<u32>);
366impl_map_from!(NonZero<u64>);
367impl_map_from!(NonZero<u128>);
368
369macro_rules! impl_try_from {
370 ($from:ty) => {
371 impl TryFrom<$from> for NonZeroU256 {
372 type Error = &'static str;
373
374 #[inline]
375 fn try_from(value: $from) -> Result<NonZeroU256, &'static str> {
376 NonZeroU256::new(U256::from(value)).ok_or("integer value is zero")
377 }
378 }
379 };
380}
381
382impl_try_from!(u8);
383impl_try_from!(u16);
384impl_try_from!(u32);
385impl_try_from!(u64);
386impl_try_from!(u128);
387
388#[doc(hidden)]
389macro_rules! panic_on_overflow {
390 ($name: expr) => {
391 if $name {
392 panic!("arithmetic operation overflow")
393 }
394 };
395}
396
397impl<T> core::ops::Add<T> for NonZeroU256
398where
399 T: Into<U256>,
400{
401 type Output = NonZeroU256;
402
403 fn add(self, other: T) -> NonZeroU256 {
404 let (result, overflow) = self.overflowing_add(other.into());
405 panic_on_overflow!(overflow);
406 result
407 }
408}
409
410impl<T> core::ops::Add<T> for &NonZeroU256
411where
412 T: Into<U256>,
413{
414 type Output = NonZeroU256;
415
416 fn add(self, other: T) -> NonZeroU256 {
417 *self + other
418 }
419}
420
421impl<T> core::ops::AddAssign<T> for NonZeroU256
422where
423 T: Into<U256>,
424{
425 fn add_assign(&mut self, other: T) {
426 let (result, overflow) = self.overflowing_add(other.into());
427 panic_on_overflow!(overflow);
428 *self = result
429 }
430}
431
432impl<T> core::ops::Sub<T> for NonZeroU256
433where
434 T: Into<U256>,
435{
436 type Output = NonZeroU256;
437
438 #[inline]
439 fn sub(self, other: T) -> NonZeroU256 {
440 let (result, overflow) = self.overflowing_sub(other.into());
441 panic_on_overflow!(overflow);
442 result
443 }
444}
445
446impl<T> core::ops::Sub<T> for &NonZeroU256
447where
448 T: Into<U256>,
449{
450 type Output = NonZeroU256;
451
452 fn sub(self, other: T) -> NonZeroU256 {
453 *self - other
454 }
455}
456
457impl<T> core::ops::SubAssign<T> for NonZeroU256
458where
459 T: Into<U256>,
460{
461 fn sub_assign(&mut self, other: T) {
462 let (result, overflow) = self.overflowing_sub(other.into());
463 panic_on_overflow!(overflow);
464 *self = result
465 }
466}
467
468impl core::ops::Mul<NonZeroU256> for NonZeroU256 {
469 type Output = NonZeroU256;
470
471 fn mul(self, other: NonZeroU256) -> NonZeroU256 {
472 let (result, overflow) = self.overflowing_mul(other);
473 panic_on_overflow!(overflow);
474 result
475 }
476}
477
478impl<'a> core::ops::Mul<&'a NonZeroU256> for NonZeroU256 {
479 type Output = NonZeroU256;
480
481 fn mul(self, other: &'a NonZeroU256) -> NonZeroU256 {
482 let (result, overflow) = self.overflowing_mul(*other);
483 panic_on_overflow!(overflow);
484 result
485 }
486}
487
488impl<'a> core::ops::Mul<&'a NonZeroU256> for &'a NonZeroU256 {
489 type Output = NonZeroU256;
490
491 fn mul(self, other: &'a NonZeroU256) -> NonZeroU256 {
492 let (result, overflow) = self.overflowing_mul(*other);
493 panic_on_overflow!(overflow);
494 result
495 }
496}
497
498impl core::ops::Mul<NonZeroU256> for &NonZeroU256 {
499 type Output = NonZeroU256;
500
501 fn mul(self, other: NonZeroU256) -> NonZeroU256 {
502 let (result, overflow) = self.overflowing_mul(other);
503 panic_on_overflow!(overflow);
504 result
505 }
506}
507
508impl core::ops::MulAssign<NonZeroU256> for NonZeroU256 {
509 fn mul_assign(&mut self, other: NonZeroU256) {
510 let result = *self * other;
511 *self = result
512 }
513}
514
515#[cfg(feature = "codec")]
516macro_rules! impl_for_non_zero {
517 ( $( $name:ty ),* $(,)? ) => {
518 $(
519 impl Encode for $name {
520 fn size_hint(&self) -> usize {
521 self.get().size_hint()
522 }
523
524 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
525 self.get().encode_to(dest)
526 }
527
528 fn encode(&self) -> Vec<u8> {
529 self.get().encode()
530 }
531
532 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
533 self.get().using_encoded(f)
534 }
535 }
536
537 impl EncodeLike for $name {}
538
539 impl Decode for $name {
540 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
541 Self::new(Decode::decode(input)?)
542 .ok_or_else(|| Error::from("cannot create non-zero number from 0"))
543 }
544 }
545 )*
546 }
547}
548
549#[cfg(feature = "codec")]
550impl_for_non_zero!(NonZeroU256);
551
552#[cfg(test)]
553mod tests {
554 extern crate alloc;
555
556 use super::*;
557 use alloc::format;
558
559 #[test]
560 fn nonzero_u256_from_to_u256() {
561 let u256 = U256::from(42u64);
562 let nz = NonZeroU256::new(u256).unwrap();
563 assert_eq!(u256, nz.into());
564 assert_eq!(format!("{u256}"), format!("{nz}"));
565 assert_eq!(format!("{u256:?}"), format!("{nz:?}"));
566 }
567
568 #[test]
569 fn nonzero_u256_from_nz64() {
570 let nzu64 = NonZero::<u64>::new(42u64).unwrap();
571 let nz: NonZeroU256 = nzu64.into();
572 assert_eq!(U256::from(nzu64.get()), nz.get());
573 }
574
575 #[test]
576 fn nonzero_u256_from_zero() {
577 let zero = 0u64;
578 let opt = NonZeroU256::new(U256::from(zero));
579 assert_eq!(None, opt);
580 let res = TryInto::<NonZeroU256>::try_into(zero);
581 assert_eq!(Err("integer value is zero"), res);
582 }
583
584 #[test]
585 fn nonzero_u256_overflowing_add() {
586 let nzu256 = NonZeroU256::MAX;
587 let result = nzu256.overflowing_add(1u64.into());
588 assert_eq!((NonZeroU256::MIN, true), result);
589 }
590
591 #[test]
592 fn nonzero_u256_overflowing_sub() {
593 let nzu256 = NonZeroU256::MIN;
594 let result = nzu256.overflowing_sub(1u64.into());
595 assert_eq!((NonZeroU256::MAX, true), result);
596 }
597
598 #[test]
599 fn nonzero_u256_overflowing_mul() {
600 let mut nzu256 = NonZeroU256::from(NonZero::<u128>::MAX);
601 nzu256 += 1;
602 let result = nzu256.overflowing_mul(nzu256);
603 assert_eq!((NonZeroU256::MAX, true), result);
604 }
605
606 #[test]
607 fn nonzero_u256_overflowing_pow() {
608 let mut nzu256 = NonZeroU256::from(NonZero::<u128>::MAX);
609 nzu256 += 1;
610 let result: (NonZeroU256, bool) = nzu256.overflowing_pow(2.into());
611 assert_eq!((NonZeroU256::MAX, true), result);
612 }
613}