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 prelude::vec::Vec,
32 scale::{Decode, Encode, EncodeLike, Error, Input, Output},
33 TypeInfo,
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() {
154 None
155 } else {
156 Some(Self(n))
157 }
158 }
159
160 #[must_use]
167 #[inline]
168 pub const unsafe fn new_unchecked(n: U256) -> Self {
169 unsafe { transmute(n) }
171 }
172
173 #[inline]
175 pub const fn get(self) -> U256 {
176 match Self::new(self.0) {
184 Some(Self(n)) => n,
185 None => {
186 unreachable!()
188 }
189 }
190 }
191
192 #[inline]
196 pub fn checked_add(self, other: U256) -> Option<Self> {
197 self.get()
205 .checked_add(other)
206 .map(|result| unsafe { Self::new_unchecked(result) })
207 }
208
209 #[inline]
211 pub fn saturating_add(self, other: U256) -> Self {
212 unsafe { Self::new_unchecked(self.get().saturating_add(other)) }
220 }
221
222 #[inline(always)]
224 pub fn overflowing_add(self, other: U256) -> (Self, bool) {
225 let result = self.get().overflowing_add(other);
226 if result.0.is_zero() {
227 (Self::MIN, true)
228 } else {
229 unsafe { (Self::new_unchecked(result.0), result.1) }
230 }
231 }
232
233 pub fn checked_sub(self, other: U256) -> Option<Self> {
235 match self.get().overflowing_sub(other) {
236 (_, true) => None,
237 (val, _) => Self::new(val),
238 }
239 }
240
241 pub fn saturating_sub(self, other: U256) -> Self {
243 match self.get().overflowing_sub(other) {
244 (_, true) => Self::MIN,
245 (val, false) => Self::new(val).unwrap_or(Self::MIN),
246 }
247 }
248
249 #[inline(always)]
251 pub fn overflowing_sub(self, other: U256) -> (Self, bool) {
252 let result = self.get().overflowing_sub(other);
253 if result.0.is_zero() {
254 (Self::MAX, true)
255 } else {
256 unsafe { (Self::new_unchecked(result.0), result.1) }
257 }
258 }
259
260 #[inline]
264 pub fn checked_mul(self, other: Self) -> Option<Self> {
265 self.get()
273 .checked_mul(other.get())
274 .map(|result| unsafe { Self::new_unchecked(result) })
275 }
276
277 #[inline]
279 pub fn saturating_mul(self, other: Self) -> Self {
280 unsafe { Self::new_unchecked(self.get().saturating_mul(other.get())) }
289 }
290
291 #[inline(always)]
293 pub fn overflowing_mul(self, other: Self) -> (Self, bool) {
294 let result = self.get().overflowing_mul(other.get());
295 if result.0.is_zero() {
296 (Self::MAX, true)
297 } else {
298 unsafe { (Self::new_unchecked(result.0), result.1) }
299 }
300 }
301
302 #[inline]
306 pub fn checked_pow(self, other: U256) -> Option<Self> {
307 self.get()
315 .checked_pow(other)
316 .map(|result| unsafe { Self::new_unchecked(result) })
317 }
318
319 #[inline]
321 pub fn overflowing_pow(self, other: U256) -> (Self, bool) {
322 let result = self.get().overflowing_pow(other);
323 if result.0.is_zero() {
324 (Self::MAX, true)
325 } else {
326 unsafe { (Self::new_unchecked(result.0), result.1) }
327 }
328 }
329
330 #[inline]
337 pub fn pow(self, other: U256) -> Self {
338 unsafe { Self::new_unchecked(self.get().pow(other)) }
346 }
347}
348
349impl From<NonZeroU256> for U256 {
350 #[inline]
351 fn from(nonzero: NonZeroU256) -> Self {
352 nonzero.get()
354 }
355}
356
357macro_rules! impl_map_from {
358 ($from:ty) => {
359 impl From<$from> for NonZeroU256 {
360 fn from(value: $from) -> Self {
361 unsafe { Self::new_unchecked(U256::from(value.get())) }
362 }
363 }
364 };
365}
366
367impl_map_from!(NonZero<u8>);
368impl_map_from!(NonZero<u16>);
369impl_map_from!(NonZero<u32>);
370impl_map_from!(NonZero<u64>);
371impl_map_from!(NonZero<u128>);
372
373macro_rules! impl_try_from {
374 ($from:ty) => {
375 impl TryFrom<$from> for NonZeroU256 {
376 type Error = &'static str;
377
378 #[inline]
379 fn try_from(value: $from) -> Result<NonZeroU256, &'static str> {
380 NonZeroU256::new(U256::from(value)).ok_or("integer value is zero")
381 }
382 }
383 };
384}
385
386impl_try_from!(u8);
387impl_try_from!(u16);
388impl_try_from!(u32);
389impl_try_from!(u64);
390impl_try_from!(u128);
391
392#[doc(hidden)]
393macro_rules! panic_on_overflow {
394 ($name: expr) => {
395 if $name {
396 panic!("arithmetic operation overflow")
397 }
398 };
399}
400
401impl<T> core::ops::Add<T> for NonZeroU256
402where
403 T: Into<U256>,
404{
405 type Output = NonZeroU256;
406
407 fn add(self, other: T) -> NonZeroU256 {
408 let (result, overflow) = self.overflowing_add(other.into());
409 panic_on_overflow!(overflow);
410 result
411 }
412}
413
414impl<T> core::ops::Add<T> for &NonZeroU256
415where
416 T: Into<U256>,
417{
418 type Output = NonZeroU256;
419
420 fn add(self, other: T) -> NonZeroU256 {
421 *self + other
422 }
423}
424
425impl<T> core::ops::AddAssign<T> for NonZeroU256
426where
427 T: Into<U256>,
428{
429 fn add_assign(&mut self, other: T) {
430 let (result, overflow) = self.overflowing_add(other.into());
431 panic_on_overflow!(overflow);
432 *self = result
433 }
434}
435
436impl<T> core::ops::Sub<T> for NonZeroU256
437where
438 T: Into<U256>,
439{
440 type Output = NonZeroU256;
441
442 #[inline]
443 fn sub(self, other: T) -> NonZeroU256 {
444 let (result, overflow) = self.overflowing_sub(other.into());
445 panic_on_overflow!(overflow);
446 result
447 }
448}
449
450impl<T> core::ops::Sub<T> for &NonZeroU256
451where
452 T: Into<U256>,
453{
454 type Output = NonZeroU256;
455
456 fn sub(self, other: T) -> NonZeroU256 {
457 *self - other
458 }
459}
460
461impl<T> core::ops::SubAssign<T> for NonZeroU256
462where
463 T: Into<U256>,
464{
465 fn sub_assign(&mut self, other: T) {
466 let (result, overflow) = self.overflowing_sub(other.into());
467 panic_on_overflow!(overflow);
468 *self = result
469 }
470}
471
472impl core::ops::Mul<NonZeroU256> for NonZeroU256 {
473 type Output = NonZeroU256;
474
475 fn mul(self, other: NonZeroU256) -> NonZeroU256 {
476 let (result, overflow) = self.overflowing_mul(other);
477 panic_on_overflow!(overflow);
478 result
479 }
480}
481
482impl<'a> core::ops::Mul<&'a NonZeroU256> for NonZeroU256 {
483 type Output = NonZeroU256;
484
485 fn mul(self, other: &'a NonZeroU256) -> NonZeroU256 {
486 let (result, overflow) = self.overflowing_mul(*other);
487 panic_on_overflow!(overflow);
488 result
489 }
490}
491
492impl<'a> core::ops::Mul<&'a NonZeroU256> for &'a NonZeroU256 {
493 type Output = NonZeroU256;
494
495 fn mul(self, other: &'a NonZeroU256) -> NonZeroU256 {
496 let (result, overflow) = self.overflowing_mul(*other);
497 panic_on_overflow!(overflow);
498 result
499 }
500}
501
502impl core::ops::Mul<NonZeroU256> for &NonZeroU256 {
503 type Output = NonZeroU256;
504
505 fn mul(self, other: NonZeroU256) -> NonZeroU256 {
506 let (result, overflow) = self.overflowing_mul(other);
507 panic_on_overflow!(overflow);
508 result
509 }
510}
511
512impl core::ops::MulAssign<NonZeroU256> for NonZeroU256 {
513 fn mul_assign(&mut self, other: NonZeroU256) {
514 let result = *self * other;
515 *self = result
516 }
517}
518
519#[cfg(feature = "codec")]
520macro_rules! impl_for_non_zero {
521 ( $( $name:ty ),* $(,)? ) => {
522 $(
523 impl Encode for $name {
524 fn size_hint(&self) -> usize {
525 self.get().size_hint()
526 }
527
528 fn encode_to<W: Output + ?Sized>(&self, dest: &mut W) {
529 self.get().encode_to(dest)
530 }
531
532 fn encode(&self) -> Vec<u8> {
533 self.get().encode()
534 }
535
536 fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
537 self.get().using_encoded(f)
538 }
539 }
540
541 impl EncodeLike for $name {}
542
543 impl Decode for $name {
544 fn decode<I: Input>(input: &mut I) -> Result<Self, Error> {
545 Self::new(Decode::decode(input)?)
546 .ok_or_else(|| Error::from("cannot create non-zero number from 0"))
547 }
548 }
549 )*
550 }
551}
552
553#[cfg(feature = "codec")]
554impl_for_non_zero!(NonZeroU256);
555
556#[cfg(test)]
557mod tests {
558 extern crate alloc;
559
560 use super::*;
561 use alloc::format;
562
563 #[test]
564 fn nonzero_u256_from_to_u256() {
565 let u256 = U256::from(42u64);
566 let nz = NonZeroU256::new(u256).unwrap();
567 assert_eq!(u256, nz.into());
568 assert_eq!(format!("{u256}"), format!("{nz}"));
569 assert_eq!(format!("{u256:?}"), format!("{nz:?}"));
570 }
571
572 #[test]
573 fn nonzero_u256_from_nz64() {
574 let nzu64 = NonZero::<u64>::new(42u64).unwrap();
575 let nz: NonZeroU256 = nzu64.into();
576 assert_eq!(U256::from(nzu64.get()), nz.get());
577 }
578
579 #[test]
580 fn nonzero_u256_from_zero() {
581 let zero = 0u64;
582 let opt = NonZeroU256::new(U256::from(zero));
583 assert_eq!(None, opt);
584 let res = TryInto::<NonZeroU256>::try_into(zero);
585 assert_eq!(Err("integer value is zero"), res);
586 }
587
588 #[test]
589 fn nonzero_u256_overflowing_add() {
590 let nzu256 = NonZeroU256::MAX;
591 let result = nzu256.overflowing_add(1u64.into());
592 assert_eq!((NonZeroU256::MIN, true), result);
593 }
594
595 #[test]
596 fn nonzero_u256_overflowing_sub() {
597 let nzu256 = NonZeroU256::MIN;
598 let result = nzu256.overflowing_sub(1u64.into());
599 assert_eq!((NonZeroU256::MAX, true), result);
600 }
601
602 #[test]
603 fn nonzero_u256_overflowing_mul() {
604 let mut nzu256 = NonZeroU256::from(NonZero::<u128>::MAX);
605 nzu256 += 1;
606 let result = nzu256.overflowing_mul(nzu256);
607 assert_eq!((NonZeroU256::MAX, true), result);
608 }
609
610 #[test]
611 fn nonzero_u256_overflowing_pow() {
612 let mut nzu256 = NonZeroU256::from(NonZero::<u128>::MAX);
613 nzu256 += 1;
614 let result: (NonZeroU256, bool) = nzu256.overflowing_pow(2.into());
615 assert_eq!((NonZeroU256::MAX, true), result);
616 }
617}