sp_arithmetic/
traits.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Primitive traits for the runtime arithmetic.
19
20use codec::HasCompact;
21use core::ops::{
22	Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, Shr, Sub, SubAssign,
23};
24pub use ensure::{
25	ensure_pow, Ensure, EnsureAdd, EnsureAddAssign, EnsureDiv, EnsureDivAssign,
26	EnsureFixedPointNumber, EnsureFrom, EnsureInto, EnsureMul, EnsureMulAssign, EnsureOp,
27	EnsureOpAssign, EnsureSub, EnsureSubAssign,
28};
29pub use integer_sqrt::IntegerSquareRoot;
30pub use num_traits::{
31	checked_pow, Bounded, CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl,
32	CheckedShr, CheckedSub, One, Signed, Unsigned, Zero,
33};
34
35use crate::MultiplyRational;
36
37/// A meta trait for arithmetic type operations, regardless of any limitation on size.
38pub trait BaseArithmetic:
39	From<u8>
40	+ Zero
41	+ One
42	+ IntegerSquareRoot
43	+ Add<Self, Output = Self>
44	+ AddAssign<Self>
45	+ Sub<Self, Output = Self>
46	+ SubAssign<Self>
47	+ Mul<Self, Output = Self>
48	+ MulAssign<Self>
49	+ Div<Self, Output = Self>
50	+ DivAssign<Self>
51	+ Rem<Self, Output = Self>
52	+ RemAssign<Self>
53	+ Shl<u32, Output = Self>
54	+ Shr<u32, Output = Self>
55	+ CheckedShl
56	+ CheckedShr
57	+ CheckedAdd
58	+ CheckedSub
59	+ CheckedMul
60	+ CheckedDiv
61	+ CheckedRem
62	+ CheckedNeg
63	+ Ensure
64	+ Saturating
65	+ PartialOrd<Self>
66	+ Ord
67	+ Bounded
68	+ HasCompact
69	+ Sized
70	+ Clone
71	+ TryFrom<u8>
72	+ TryInto<u8>
73	+ TryFrom<u16>
74	+ TryInto<u16>
75	+ TryFrom<u32>
76	+ TryInto<u32>
77	+ TryFrom<u64>
78	+ TryInto<u64>
79	+ TryFrom<u128>
80	+ TryInto<u128>
81	+ TryFrom<usize>
82	+ TryInto<usize>
83	+ UniqueSaturatedFrom<u8>
84	+ UniqueSaturatedInto<u8>
85	+ UniqueSaturatedFrom<u16>
86	+ UniqueSaturatedInto<u16>
87	+ UniqueSaturatedFrom<u32>
88	+ UniqueSaturatedInto<u32>
89	+ UniqueSaturatedFrom<u64>
90	+ UniqueSaturatedInto<u64>
91	+ UniqueSaturatedFrom<u128>
92	+ UniqueSaturatedInto<u128>
93{
94}
95
96impl<
97		T: From<u8>
98			+ Zero
99			+ One
100			+ IntegerSquareRoot
101			+ Add<Self, Output = Self>
102			+ AddAssign<Self>
103			+ Sub<Self, Output = Self>
104			+ SubAssign<Self>
105			+ Mul<Self, Output = Self>
106			+ MulAssign<Self>
107			+ Div<Self, Output = Self>
108			+ DivAssign<Self>
109			+ Rem<Self, Output = Self>
110			+ RemAssign<Self>
111			+ Shl<u32, Output = Self>
112			+ Shr<u32, Output = Self>
113			+ CheckedShl
114			+ CheckedShr
115			+ CheckedAdd
116			+ CheckedSub
117			+ CheckedMul
118			+ CheckedDiv
119			+ CheckedRem
120			+ CheckedNeg
121			+ Ensure
122			+ Saturating
123			+ PartialOrd<Self>
124			+ Ord
125			+ Bounded
126			+ HasCompact
127			+ Sized
128			+ Clone
129			+ TryFrom<u8>
130			+ TryInto<u8>
131			+ TryFrom<u16>
132			+ TryInto<u16>
133			+ TryFrom<u32>
134			+ TryInto<u32>
135			+ TryFrom<u64>
136			+ TryInto<u64>
137			+ TryFrom<u128>
138			+ TryInto<u128>
139			+ TryFrom<usize>
140			+ TryInto<usize>
141			+ UniqueSaturatedFrom<u8>
142			+ UniqueSaturatedInto<u8>
143			+ UniqueSaturatedFrom<u16>
144			+ UniqueSaturatedInto<u16>
145			+ UniqueSaturatedFrom<u32>
146			+ UniqueSaturatedInto<u32>
147			+ UniqueSaturatedFrom<u64>
148			+ UniqueSaturatedInto<u64>
149			+ UniqueSaturatedFrom<u128>
150			+ UniqueSaturatedInto<u128>,
151	> BaseArithmetic for T
152{
153}
154
155/// A meta trait for arithmetic.
156///
157/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
158/// be able to represent at least `u8` values without loss, hence the trait implies `From<u8>`
159/// and smaller integers. All other conversions are fallible.
160pub trait AtLeast8Bit: BaseArithmetic + From<u8> {}
161
162impl<T: BaseArithmetic + From<u8>> AtLeast8Bit for T {}
163
164/// A meta trait for arithmetic.  Same as [`AtLeast8Bit `], but also bounded to be unsigned.
165pub trait AtLeast8BitUnsigned: AtLeast8Bit + Unsigned {}
166
167impl<T: AtLeast8Bit + Unsigned> AtLeast8BitUnsigned for T {}
168
169/// A meta trait for arithmetic.
170///
171/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
172/// be able to represent at least `u16` values without loss, hence the trait implies `From<u16>`
173/// and smaller integers. All other conversions are fallible.
174pub trait AtLeast16Bit: BaseArithmetic + From<u16> {}
175
176impl<T: BaseArithmetic + From<u16>> AtLeast16Bit for T {}
177
178/// A meta trait for arithmetic.  Same as [`AtLeast16Bit `], but also bounded to be unsigned.
179pub trait AtLeast16BitUnsigned: AtLeast16Bit + Unsigned {}
180
181impl<T: AtLeast16Bit + Unsigned> AtLeast16BitUnsigned for T {}
182
183/// A meta trait for arithmetic.
184///
185/// Arithmetic types do all the usual stuff you'd expect numbers to do. They are guaranteed to
186/// be able to represent at least `u32` values without loss, hence the trait implies `From<u32>`
187/// and smaller integers. All other conversions are fallible.
188pub trait AtLeast32Bit: BaseArithmetic + From<u16> + From<u32> {}
189
190impl<T: BaseArithmetic + From<u16> + From<u32>> AtLeast32Bit for T {}
191
192/// A meta trait for arithmetic.  Same as [`AtLeast32Bit `], but also bounded to be unsigned.
193pub trait AtLeast32BitUnsigned: AtLeast32Bit + Unsigned + MultiplyRational {}
194
195impl<T: AtLeast32Bit + Unsigned + MultiplyRational> AtLeast32BitUnsigned for T {}
196
197/// Just like `From` except that if the source value is too big to fit into the destination type
198/// then it'll saturate the destination.
199pub trait UniqueSaturatedFrom<T: Sized>: Sized {
200	/// Convert from a value of `T` into an equivalent instance of `Self`.
201	fn unique_saturated_from(t: T) -> Self;
202}
203
204/// Just like `Into` except that if the source value is too big to fit into the destination type
205/// then it'll saturate the destination.
206pub trait UniqueSaturatedInto<T: Sized>: Sized {
207	/// Consume self to return an equivalent value of `T`.
208	fn unique_saturated_into(self) -> T;
209}
210
211impl<T: Sized, S: TryFrom<T> + Bounded + Sized> UniqueSaturatedFrom<T> for S {
212	fn unique_saturated_from(t: T) -> Self {
213		S::try_from(t).unwrap_or_else(|_| Bounded::max_value())
214	}
215}
216
217impl<T: Bounded + Sized, S: TryInto<T> + Sized> UniqueSaturatedInto<T> for S {
218	fn unique_saturated_into(self) -> T {
219		self.try_into().unwrap_or_else(|_| Bounded::max_value())
220	}
221}
222
223/// Saturating arithmetic operations, returning maximum or minimum values instead of overflowing.
224pub trait Saturating {
225	/// Saturating addition. Compute `self + rhs`, saturating at the numeric bounds instead of
226	/// overflowing.
227	fn saturating_add(self, rhs: Self) -> Self;
228
229	/// Saturating subtraction. Compute `self - rhs`, saturating at the numeric bounds instead of
230	/// overflowing.
231	fn saturating_sub(self, rhs: Self) -> Self;
232
233	/// Saturating multiply. Compute `self * rhs`, saturating at the numeric bounds instead of
234	/// overflowing.
235	fn saturating_mul(self, rhs: Self) -> Self;
236
237	/// Saturating exponentiation. Compute `self.pow(exp)`, saturating at the numeric bounds
238	/// instead of overflowing.
239	fn saturating_pow(self, exp: usize) -> Self;
240
241	/// Decrement self by one, saturating at zero.
242	fn saturating_less_one(mut self) -> Self
243	where
244		Self: One,
245	{
246		self.saturating_dec();
247		self
248	}
249
250	/// Increment self by one, saturating at the numeric bounds instead of overflowing.
251	fn saturating_plus_one(mut self) -> Self
252	where
253		Self: One,
254	{
255		self.saturating_inc();
256		self
257	}
258
259	/// Increment self by one, saturating.
260	fn saturating_inc(&mut self)
261	where
262		Self: One,
263	{
264		let mut o = Self::one();
265		core::mem::swap(&mut o, self);
266		*self = o.saturating_add(One::one());
267	}
268
269	/// Decrement self by one, saturating at zero.
270	fn saturating_dec(&mut self)
271	where
272		Self: One,
273	{
274		let mut o = Self::one();
275		core::mem::swap(&mut o, self);
276		*self = o.saturating_sub(One::one());
277	}
278
279	/// Increment self by some `amount`, saturating.
280	fn saturating_accrue(&mut self, amount: Self)
281	where
282		Self: One,
283	{
284		let mut o = Self::one();
285		core::mem::swap(&mut o, self);
286		*self = o.saturating_add(amount);
287	}
288
289	/// Decrement self by some `amount`, saturating at zero.
290	fn saturating_reduce(&mut self, amount: Self)
291	where
292		Self: One,
293	{
294		let mut o = Self::one();
295		core::mem::swap(&mut o, self);
296		*self = o.saturating_sub(amount);
297	}
298}
299
300impl<T: Clone + Zero + One + PartialOrd + CheckedMul + Bounded + num_traits::Saturating> Saturating
301	for T
302{
303	fn saturating_add(self, o: Self) -> Self {
304		<Self as num_traits::Saturating>::saturating_add(self, o)
305	}
306
307	fn saturating_sub(self, o: Self) -> Self {
308		<Self as num_traits::Saturating>::saturating_sub(self, o)
309	}
310
311	fn saturating_mul(self, o: Self) -> Self {
312		self.checked_mul(&o).unwrap_or_else(|| {
313			if (self < T::zero()) != (o < T::zero()) {
314				Bounded::min_value()
315			} else {
316				Bounded::max_value()
317			}
318		})
319	}
320
321	fn saturating_pow(self, exp: usize) -> Self {
322		let neg = self < T::zero() && exp % 2 != 0;
323		checked_pow(self, exp).unwrap_or_else(|| {
324			if neg {
325				Bounded::min_value()
326			} else {
327				Bounded::max_value()
328			}
329		})
330	}
331}
332
333/// Convenience type to work around the highly unergonomic syntax needed
334/// to invoke the functions of overloaded generic traits, in this case
335/// `SaturatedFrom` and `SaturatedInto`.
336pub trait SaturatedConversion {
337	/// Convert from a value of `T` into an equivalent instance of `Self`.
338	///
339	/// This just uses `UniqueSaturatedFrom` internally but with this
340	/// variant you can provide the destination type using turbofish syntax
341	/// in case Rust happens not to assume the correct type.
342	fn saturated_from<T>(t: T) -> Self
343	where
344		Self: UniqueSaturatedFrom<T>,
345	{
346		<Self as UniqueSaturatedFrom<T>>::unique_saturated_from(t)
347	}
348
349	/// Consume self to return an equivalent value of `T`.
350	///
351	/// This just uses `UniqueSaturatedInto` internally but with this
352	/// variant you can provide the destination type using turbofish syntax
353	/// in case Rust happens not to assume the correct type.
354	fn saturated_into<T>(self) -> T
355	where
356		Self: UniqueSaturatedInto<T>,
357	{
358		<Self as UniqueSaturatedInto<T>>::unique_saturated_into(self)
359	}
360}
361impl<T: Sized> SaturatedConversion for T {}
362
363/// Arithmetic operations with safe error handling.
364///
365/// This module provide a readable way to do safe arithmetics, turning this:
366///
367/// ```
368/// # use sp_arithmetic::{traits::EnsureSub, ArithmeticError};
369/// # fn foo() -> Result<(), ArithmeticError> {
370/// # let mut my_value: i32 = 1;
371/// # let other_value: i32 = 1;
372/// my_value = my_value.checked_sub(other_value).ok_or(ArithmeticError::Overflow)?;
373/// # Ok(())
374/// # }
375/// ```
376///
377/// into this:
378///
379/// ```
380/// # use sp_arithmetic::{traits::EnsureSubAssign, ArithmeticError};
381/// # fn foo() -> Result<(), ArithmeticError> {
382/// # let mut my_value: i32 = 1;
383/// # let other_value: i32 = 1;
384/// my_value.ensure_sub_assign(other_value)?;
385/// # Ok(())
386/// # }
387/// ```
388///
389/// choosing the correct [`ArithmeticError`](crate::ArithmeticError) it should return in case of
390/// fail.
391///
392/// The *EnsureOps* family functions follows the same behavior as *CheckedOps* but
393/// returning an [`ArithmeticError`](crate::ArithmeticError) instead of `None`.
394mod ensure {
395	use super::{checked_pow, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, One, Zero};
396	use crate::{ArithmeticError, FixedPointNumber, FixedPointOperand};
397
398	/// Performs addition that returns [`ArithmeticError`] instead of wrapping around on overflow.
399	pub trait EnsureAdd: EnsureAddAssign {
400		/// Adds two numbers, checking for overflow.
401		///
402		/// If it fails, [`ArithmeticError`] is returned.
403		///
404		/// Similar to [`CheckedAdd::checked_add()`] but returning an [`ArithmeticError`] error.
405		///
406		/// # Examples
407		///
408		/// ```
409		/// use sp_arithmetic::traits::EnsureAdd;
410		///
411		/// let a: i32 = 10;
412		/// let b: i32 = 20;
413		///
414		/// assert_eq!(a.ensure_add(b), Ok(30));
415		/// ```
416		///
417		/// ```
418		/// use sp_arithmetic::{traits::EnsureAdd, ArithmeticError};
419		///
420		/// fn overflow() -> Result<(), ArithmeticError> {
421		///     u32::MAX.ensure_add(1)?;
422		///     Ok(())
423		/// }
424		///
425		/// fn underflow() -> Result<(), ArithmeticError> {
426		///     i32::MIN.ensure_add(-1)?;
427		///     Ok(())
428		/// }
429		///
430		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
431		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
432		/// ```
433		fn ensure_add(mut self, v: Self) -> Result<Self, ArithmeticError> {
434			self.ensure_add_assign(v)?;
435			Ok(self)
436		}
437	}
438
439	/// Performs subtraction that returns [`ArithmeticError`] instead of wrapping around on
440	/// underflow.
441	pub trait EnsureSub: EnsureSubAssign {
442		/// Subtracts two numbers, checking for overflow.
443		///
444		/// If it fails, [`ArithmeticError`] is returned.
445		///
446		/// Similar to [`CheckedSub::checked_sub()`] but returning an [`ArithmeticError`] error.
447		///
448		/// # Examples
449		///
450		/// ```
451		/// use sp_arithmetic::traits::EnsureSub;
452		///
453		/// let a: i32 = 10;
454		/// let b: i32 = 20;
455		///
456		/// assert_eq!(a.ensure_sub(b), Ok(-10));
457		/// ```
458		///
459		/// ```
460		/// use sp_arithmetic::{traits::EnsureSub, ArithmeticError};
461		///
462		/// fn underflow() -> Result<(), ArithmeticError> {
463		///     0u32.ensure_sub(1)?;
464		///     Ok(())
465		/// }
466		///
467		/// fn overflow() -> Result<(), ArithmeticError> {
468		///     i32::MAX.ensure_sub(-1)?;
469		///     Ok(())
470		/// }
471		///
472		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
473		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
474		/// ```
475		fn ensure_sub(mut self, v: Self) -> Result<Self, ArithmeticError> {
476			self.ensure_sub_assign(v)?;
477			Ok(self)
478		}
479	}
480
481	/// Performs multiplication that returns [`ArithmeticError`] instead of wrapping around on
482	/// overflow.
483	pub trait EnsureMul: EnsureMulAssign {
484		/// Multiplies two numbers, checking for overflow.
485		///
486		/// If it fails, [`ArithmeticError`] is returned.
487		///
488		/// Similar to [`CheckedMul::checked_mul()`] but returning an [`ArithmeticError`] error.
489		///
490		/// # Examples
491		///
492		/// ```
493		/// use sp_arithmetic::traits::EnsureMul;
494		///
495		/// let a: i32 = 10;
496		/// let b: i32 = 20;
497		///
498		/// assert_eq!(a.ensure_mul(b), Ok(200));
499		/// ```
500		///
501		/// ```
502		/// use sp_arithmetic::{traits::EnsureMul, ArithmeticError};
503		///
504		/// fn overflow() -> Result<(), ArithmeticError> {
505		///     u32::MAX.ensure_mul(2)?;
506		///     Ok(())
507		/// }
508		///
509		/// fn underflow() -> Result<(), ArithmeticError> {
510		///     i32::MAX.ensure_mul(-2)?;
511		///     Ok(())
512		/// }
513		///
514		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
515		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
516		/// ```
517		fn ensure_mul(mut self, v: Self) -> Result<Self, ArithmeticError> {
518			self.ensure_mul_assign(v)?;
519			Ok(self)
520		}
521	}
522
523	/// Performs division that returns [`ArithmeticError`] instead of wrapping around on overflow.
524	pub trait EnsureDiv: EnsureDivAssign {
525		/// Divides two numbers, checking for overflow.
526		///
527		/// If it fails, [`ArithmeticError`] is returned.
528		///
529		/// Similar to [`CheckedDiv::checked_div()`] but returning an [`ArithmeticError`] error.
530		///
531		/// # Examples
532		///
533		/// ```
534		/// use sp_arithmetic::traits::EnsureDiv;
535		///
536		/// let a: i32 = 20;
537		/// let b: i32 = 10;
538		///
539		/// assert_eq!(a.ensure_div(b), Ok(2));
540		/// ```
541		///
542		/// ```
543		/// use sp_arithmetic::{traits::EnsureDiv, ArithmeticError};
544		///
545		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
546		///     1.ensure_div(0)?;
547		///     Ok(())
548		/// }
549		///
550		/// fn overflow() -> Result<(), ArithmeticError> {
551		///     i64::MIN.ensure_div(-1)?;
552		///     Ok(())
553		/// }
554		///
555		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
556		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
557		/// ```
558		fn ensure_div(mut self, v: Self) -> Result<Self, ArithmeticError> {
559			self.ensure_div_assign(v)?;
560			Ok(self)
561		}
562	}
563
564	/// Raises a value to the power of exp, returning `ArithmeticError` if an overflow occurred.
565	///
566	/// Check [`checked_pow`] for more info about border cases.
567	///
568	/// ```
569	/// use sp_arithmetic::{traits::ensure_pow, ArithmeticError};
570	///
571	/// fn overflow() -> Result<(), ArithmeticError> {
572	///     ensure_pow(2u64, 64)?;
573	///     Ok(())
574	/// }
575	///
576	/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
577	/// ```
578	pub fn ensure_pow<T: One + CheckedMul + Clone>(
579		base: T,
580		exp: usize,
581	) -> Result<T, ArithmeticError> {
582		checked_pow(base, exp).ok_or(ArithmeticError::Overflow)
583	}
584
585	impl<T: EnsureAddAssign> EnsureAdd for T {}
586	impl<T: EnsureSubAssign> EnsureSub for T {}
587	impl<T: EnsureMulAssign> EnsureMul for T {}
588	impl<T: EnsureDivAssign> EnsureDiv for T {}
589
590	/// Meta trait that supports all immutable arithmetic `Ensure*` operations
591	pub trait EnsureOp: EnsureAdd + EnsureSub + EnsureMul + EnsureDiv {}
592	impl<T: EnsureAdd + EnsureSub + EnsureMul + EnsureDiv> EnsureOp for T {}
593
594	/// Performs self addition that returns [`ArithmeticError`] instead of wrapping around on
595	/// overflow.
596	pub trait EnsureAddAssign: CheckedAdd + PartialOrd + Zero {
597		/// Adds two numbers overwriting the left hand one, checking for overflow.
598		///
599		/// If it fails, [`ArithmeticError`] is returned.
600		///
601		/// # Examples
602		///
603		/// ```
604		/// use sp_arithmetic::traits::EnsureAddAssign;
605		///
606		/// let mut a: i32 = 10;
607		/// let b: i32 = 20;
608		///
609		/// a.ensure_add_assign(b).unwrap();
610		/// assert_eq!(a, 30);
611		/// ```
612		///
613		/// ```
614		/// use sp_arithmetic::{traits::EnsureAddAssign, ArithmeticError};
615		///
616		/// fn overflow() -> Result<(), ArithmeticError> {
617		///     let mut max = u32::MAX;
618		///     max.ensure_add_assign(1)?;
619		///     Ok(())
620		/// }
621		///
622		/// fn underflow() -> Result<(), ArithmeticError> {
623		///     let mut max = i32::MIN;
624		///     max.ensure_add_assign(-1)?;
625		///     Ok(())
626		/// }
627		///
628		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
629		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
630		/// ```
631		fn ensure_add_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
632			*self = self.checked_add(&v).ok_or_else(|| error::equivalent(&v))?;
633			Ok(())
634		}
635	}
636
637	/// Performs self subtraction that returns [`ArithmeticError`] instead of wrapping around on
638	/// underflow.
639	pub trait EnsureSubAssign: CheckedSub + PartialOrd + Zero {
640		/// Subtracts two numbers overwriting the left hand one, checking for overflow.
641		///
642		/// If it fails, [`ArithmeticError`] is returned.
643		///
644		/// # Examples
645		///
646		/// ```
647		/// use sp_arithmetic::traits::EnsureSubAssign;
648		///
649		/// let mut a: i32 = 10;
650		/// let b: i32 = 20;
651		///
652		/// a.ensure_sub_assign(b).unwrap();
653		/// assert_eq!(a, -10);
654		/// ```
655		///
656		/// ```
657		/// use sp_arithmetic::{traits::EnsureSubAssign, ArithmeticError};
658		///
659		/// fn underflow() -> Result<(), ArithmeticError> {
660		///     let mut zero: u32 = 0;
661		///     zero.ensure_sub_assign(1)?;
662		///     Ok(())
663		/// }
664		///
665		/// fn overflow() -> Result<(), ArithmeticError> {
666		///     let mut zero = i32::MAX;
667		///     zero.ensure_sub_assign(-1)?;
668		///     Ok(())
669		/// }
670		///
671		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
672		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
673		/// ```
674		fn ensure_sub_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
675			*self = self.checked_sub(&v).ok_or_else(|| error::inverse(&v))?;
676			Ok(())
677		}
678	}
679
680	/// Performs self multiplication that returns [`ArithmeticError`] instead of wrapping around on
681	/// overflow.
682	pub trait EnsureMulAssign: CheckedMul + PartialOrd + Zero {
683		/// Multiplies two numbers overwriting the left hand one, checking for overflow.
684		///
685		/// If it fails, [`ArithmeticError`] is returned.
686		///
687		/// # Examples
688		///
689		/// ```
690		/// use sp_arithmetic::traits::EnsureMulAssign;
691		///
692		/// let mut a: i32 = 10;
693		/// let b: i32 = 20;
694		///
695		/// a.ensure_mul_assign(b).unwrap();
696		/// assert_eq!(a, 200);
697		/// ```
698		///
699		/// ```
700		/// use sp_arithmetic::{traits::EnsureMulAssign, ArithmeticError};
701		///
702		/// fn overflow() -> Result<(), ArithmeticError> {
703		///     let mut max = u32::MAX;
704		///     max.ensure_mul_assign(2)?;
705		///     Ok(())
706		/// }
707		///
708		/// fn underflow() -> Result<(), ArithmeticError> {
709		///     let mut max = i32::MAX;
710		///     max.ensure_mul_assign(-2)?;
711		///     Ok(())
712		/// }
713		///
714		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
715		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
716		/// ```
717		fn ensure_mul_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
718			*self = self.checked_mul(&v).ok_or_else(|| error::multiplication(self, &v))?;
719			Ok(())
720		}
721	}
722
723	/// Performs self division that returns [`ArithmeticError`] instead of wrapping around on
724	/// overflow.
725	pub trait EnsureDivAssign: CheckedDiv + PartialOrd + Zero {
726		/// Divides two numbers overwriting the left hand one, checking for overflow.
727		///
728		/// If it fails, [`ArithmeticError`] is returned.
729		///
730		/// # Examples
731		///
732		/// ```
733		/// use sp_arithmetic::traits::EnsureDivAssign;
734		///
735		/// let mut a: i32 = 20;
736		/// let b: i32 = 10;
737		///
738		/// a.ensure_div_assign(b).unwrap();
739		/// assert_eq!(a, 2);
740		/// ```
741		///
742		/// ```
743		/// use sp_arithmetic::{traits::EnsureDivAssign, ArithmeticError, FixedI64};
744		///
745		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
746		///     let mut one = 1;
747		///     one.ensure_div_assign(0)?;
748		///     Ok(())
749		/// }
750		///
751		/// fn overflow() -> Result<(), ArithmeticError> {
752		///     let mut min = FixedI64::from(i64::MIN);
753		///     min.ensure_div_assign(FixedI64::from(-1))?;
754		///     Ok(())
755		/// }
756		///
757		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
758		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
759		/// ```
760		fn ensure_div_assign(&mut self, v: Self) -> Result<(), ArithmeticError> {
761			*self = self.checked_div(&v).ok_or_else(|| error::division(self, &v))?;
762			Ok(())
763		}
764	}
765
766	impl<T: CheckedAdd + PartialOrd + Zero> EnsureAddAssign for T {}
767	impl<T: CheckedSub + PartialOrd + Zero> EnsureSubAssign for T {}
768	impl<T: CheckedMul + PartialOrd + Zero> EnsureMulAssign for T {}
769	impl<T: CheckedDiv + PartialOrd + Zero> EnsureDivAssign for T {}
770
771	/// Meta trait that supports all assigned arithmetic `Ensure*` operations
772	pub trait EnsureOpAssign:
773		EnsureAddAssign + EnsureSubAssign + EnsureMulAssign + EnsureDivAssign
774	{
775	}
776	impl<T: EnsureAddAssign + EnsureSubAssign + EnsureMulAssign + EnsureDivAssign> EnsureOpAssign
777		for T
778	{
779	}
780
781	pub trait Ensure: EnsureOp + EnsureOpAssign {}
782	impl<T: EnsureOp + EnsureOpAssign> Ensure for T {}
783
784	/// Extends [`FixedPointNumber`] with the Ensure family functions.
785	pub trait EnsureFixedPointNumber: FixedPointNumber {
786		/// Creates `self` from a rational number. Equal to `n / d`.
787		///
788		/// Returns [`ArithmeticError`] if `d == 0` or `n / d` exceeds accuracy.
789		///
790		/// Similar to [`FixedPointNumber::checked_from_rational()`] but returning an
791		/// [`ArithmeticError`] error.
792		///
793		/// ```
794		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
795		///
796		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
797		///     FixedI64::ensure_from_rational(1, 0)?;
798		///     Ok(())
799		/// }
800		///
801		/// fn underflow() -> Result<(), ArithmeticError> {
802		///     FixedI64::ensure_from_rational(i64::MAX, -1)?;
803		///     Ok(())
804		/// }
805		///
806		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
807		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
808		/// ```
809		fn ensure_from_rational<N: FixedPointOperand, D: FixedPointOperand>(
810			n: N,
811			d: D,
812		) -> Result<Self, ArithmeticError> {
813			<Self as FixedPointNumber>::checked_from_rational(n, d)
814				.ok_or_else(|| error::division(&n, &d))
815		}
816
817		/// Ensure multiplication for integer type `N`. Equal to `self * n`.
818		///
819		/// Returns [`ArithmeticError`] if the result does not fit in `N`.
820		///
821		/// Similar to [`FixedPointNumber::checked_mul_int()`] but returning an [`ArithmeticError`]
822		/// error.
823		///
824		/// ```
825		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
826		///
827		/// fn overflow() -> Result<(), ArithmeticError> {
828		///     FixedI64::from(i64::MAX).ensure_mul_int(2)?;
829		///     Ok(())
830		/// }
831		///
832		/// fn underflow() -> Result<(), ArithmeticError> {
833		///     FixedI64::from(i64::MAX).ensure_mul_int(-2)?;
834		///     Ok(())
835		/// }
836		///
837		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
838		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
839		/// ```
840		fn ensure_mul_int<N: FixedPointOperand>(self, n: N) -> Result<N, ArithmeticError> {
841			self.checked_mul_int(n).ok_or_else(|| error::multiplication(&self, &n))
842		}
843
844		/// Ensure division for integer type `N`. Equal to `self / d`.
845		///
846		/// Returns [`ArithmeticError`] if the result does not fit in `N` or `d == 0`.
847		///
848		/// Similar to [`FixedPointNumber::checked_div_int()`] but returning an [`ArithmeticError`]
849		/// error.
850		///
851		/// ```
852		/// use sp_arithmetic::{traits::EnsureFixedPointNumber, ArithmeticError, FixedI64};
853		///
854		/// fn extrinsic_zero() -> Result<(), ArithmeticError> {
855		///     FixedI64::from(1).ensure_div_int(0)?;
856		///     Ok(())
857		/// }
858		///
859		/// fn overflow() -> Result<(), ArithmeticError> {
860		///     FixedI64::from(i64::MIN).ensure_div_int(-1)?;
861		///     Ok(())
862		/// }
863		///
864		/// assert_eq!(extrinsic_zero(), Err(ArithmeticError::DivisionByZero));
865		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
866		/// ```
867		fn ensure_div_int<D: FixedPointOperand>(self, d: D) -> Result<D, ArithmeticError> {
868			self.checked_div_int(d).ok_or_else(|| error::division(&self, &d))
869		}
870	}
871
872	impl<T: FixedPointNumber> EnsureFixedPointNumber for T {}
873
874	/// Similar to [`TryFrom`] but returning an [`ArithmeticError`] error.
875	pub trait EnsureFrom<T: PartialOrd + Zero>: TryFrom<T> + PartialOrd + Zero {
876		/// Performs the conversion returning an [`ArithmeticError`] if fails.
877		///
878		/// Similar to [`TryFrom::try_from()`] but returning an [`ArithmeticError`] error.
879		///
880		/// ```
881		/// use sp_arithmetic::{traits::EnsureFrom, ArithmeticError};
882		///
883		/// fn overflow() -> Result<(), ArithmeticError> {
884		///     let byte: u8 = u8::ensure_from(256u16)?;
885		///     Ok(())
886		/// }
887		///
888		/// fn underflow() -> Result<(), ArithmeticError> {
889		///     let byte: i8 = i8::ensure_from(-129i16)?;
890		///     Ok(())
891		/// }
892		///
893		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
894		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
895		/// ```
896		fn ensure_from(other: T) -> Result<Self, ArithmeticError> {
897			let err = error::equivalent(&other);
898			Self::try_from(other).map_err(|_| err)
899		}
900	}
901
902	/// Similar to [`TryInto`] but returning an [`ArithmeticError`] error.
903	pub trait EnsureInto<T: PartialOrd + Zero>: TryInto<T> + PartialOrd + Zero {
904		/// Performs the conversion returning an [`ArithmeticError`] if fails.
905		///
906		/// Similar to [`TryInto::try_into()`] but returning an [`ArithmeticError`] error
907		///
908		/// ```
909		/// use sp_arithmetic::{traits::EnsureInto, ArithmeticError};
910		///
911		/// fn overflow() -> Result<(), ArithmeticError> {
912		///     let byte: u8 = 256u16.ensure_into()?;
913		///     Ok(())
914		/// }
915		///
916		/// fn underflow() -> Result<(), ArithmeticError> {
917		///     let byte: i8 = (-129i16).ensure_into()?;
918		///     Ok(())
919		/// }
920		///
921		/// assert_eq!(overflow(), Err(ArithmeticError::Overflow));
922		/// assert_eq!(underflow(), Err(ArithmeticError::Underflow));
923		/// ```
924		fn ensure_into(self) -> Result<T, ArithmeticError> {
925			let err = error::equivalent(&self);
926			self.try_into().map_err(|_| err)
927		}
928	}
929
930	impl<T: TryFrom<S> + PartialOrd + Zero, S: PartialOrd + Zero> EnsureFrom<S> for T {}
931	impl<T: TryInto<S> + PartialOrd + Zero, S: PartialOrd + Zero> EnsureInto<S> for T {}
932
933	mod error {
934		use super::{ArithmeticError, Zero};
935
936		#[derive(PartialEq)]
937		enum Signum {
938			Negative,
939			Positive,
940		}
941
942		impl<T: PartialOrd + Zero> From<&T> for Signum {
943			fn from(value: &T) -> Self {
944				if value < &Zero::zero() {
945					Signum::Negative
946				} else {
947					Signum::Positive
948				}
949			}
950		}
951
952		impl core::ops::Mul for Signum {
953			type Output = Self;
954
955			fn mul(self, rhs: Self) -> Self {
956				if self != rhs {
957					Signum::Negative
958				} else {
959					Signum::Positive
960				}
961			}
962		}
963
964		pub fn equivalent<R: PartialOrd + Zero>(r: &R) -> ArithmeticError {
965			match Signum::from(r) {
966				Signum::Negative => ArithmeticError::Underflow,
967				Signum::Positive => ArithmeticError::Overflow,
968			}
969		}
970
971		pub fn inverse<R: PartialOrd + Zero>(r: &R) -> ArithmeticError {
972			match Signum::from(r) {
973				Signum::Negative => ArithmeticError::Overflow,
974				Signum::Positive => ArithmeticError::Underflow,
975			}
976		}
977
978		pub fn multiplication<L: PartialOrd + Zero, R: PartialOrd + Zero>(
979			l: &L,
980			r: &R,
981		) -> ArithmeticError {
982			match Signum::from(l) * Signum::from(r) {
983				Signum::Negative => ArithmeticError::Underflow,
984				Signum::Positive => ArithmeticError::Overflow,
985			}
986		}
987
988		pub fn division<N: PartialOrd + Zero, D: PartialOrd + Zero>(
989			n: &N,
990			d: &D,
991		) -> ArithmeticError {
992			if d.is_zero() {
993				ArithmeticError::DivisionByZero
994			} else {
995				multiplication(n, d)
996			}
997		}
998	}
999}
1000
1001#[cfg(test)]
1002mod tests {
1003	use super::*;
1004	use crate::ArithmeticError;
1005	use rand::{seq::SliceRandom, thread_rng, Rng};
1006
1007	#[test]
1008	fn ensure_add_works() {
1009		test_ensure(values(), &EnsureAdd::ensure_add, &CheckedAdd::checked_add);
1010	}
1011
1012	#[test]
1013	fn ensure_sub_works() {
1014		test_ensure(values(), &EnsureSub::ensure_sub, &CheckedSub::checked_sub);
1015	}
1016
1017	#[test]
1018	fn ensure_mul_works() {
1019		test_ensure(values(), &EnsureMul::ensure_mul, &CheckedMul::checked_mul);
1020	}
1021
1022	#[test]
1023	fn ensure_div_works() {
1024		test_ensure(values(), &EnsureDiv::ensure_div, &CheckedDiv::checked_div);
1025	}
1026
1027	#[test]
1028	fn ensure_pow_works() {
1029		test_ensure(
1030			values().into_iter().map(|(base, exp)| (base, exp as usize)).collect(),
1031			ensure_pow,
1032			|&a, &b| checked_pow(a, b),
1033		);
1034	}
1035
1036	#[test]
1037	fn ensure_add_assign_works() {
1038		test_ensure_assign(values(), &EnsureAddAssign::ensure_add_assign, &EnsureAdd::ensure_add);
1039	}
1040
1041	#[test]
1042	fn ensure_sub_assign_works() {
1043		test_ensure_assign(values(), &EnsureSubAssign::ensure_sub_assign, &EnsureSub::ensure_sub);
1044	}
1045
1046	#[test]
1047	fn ensure_mul_assign_works() {
1048		test_ensure_assign(values(), &EnsureMulAssign::ensure_mul_assign, &&EnsureMul::ensure_mul);
1049	}
1050
1051	#[test]
1052	fn ensure_div_assign_works() {
1053		test_ensure_assign(values(), &EnsureDivAssign::ensure_div_assign, &EnsureDiv::ensure_div);
1054	}
1055
1056	/// Test that the ensured function returns the expected un-ensured value.
1057	fn test_ensure<V, W, E, P>(pairs: Vec<(V, W)>, ensured: E, unensured: P)
1058	where
1059		V: Ensure + core::fmt::Debug + Copy,
1060		W: Ensure + core::fmt::Debug + Copy,
1061		E: Fn(V, W) -> Result<V, ArithmeticError>,
1062		P: Fn(&V, &W) -> Option<V>,
1063	{
1064		for (a, b) in pairs.into_iter() {
1065			match ensured(a, b) {
1066				Ok(c) => {
1067					assert_eq!(unensured(&a, &b), Some(c))
1068				},
1069				Err(_) => {
1070					assert!(unensured(&a, &b).is_none());
1071				},
1072			}
1073		}
1074	}
1075
1076	/// Test that the ensured function modifies `self` to the expected un-ensured value.
1077	fn test_ensure_assign<V, W, E, P>(pairs: Vec<(V, W)>, ensured: E, unensured: P)
1078	where
1079		V: Ensure + std::panic::RefUnwindSafe + std::panic::UnwindSafe + core::fmt::Debug + Copy,
1080		W: Ensure + std::panic::RefUnwindSafe + std::panic::UnwindSafe + core::fmt::Debug + Copy,
1081		E: Fn(&mut V, W) -> Result<(), ArithmeticError>,
1082		P: Fn(V, W) -> Result<V, ArithmeticError> + std::panic::RefUnwindSafe,
1083	{
1084		for (mut a, b) in pairs.into_iter() {
1085			let old_a = a;
1086
1087			match ensured(&mut a, b) {
1088				Ok(()) => {
1089					assert_eq!(unensured(old_a, b), Ok(a));
1090				},
1091				Err(err) => {
1092					assert_eq!(a, old_a, "A stays unmodified in the error case");
1093					assert_eq!(unensured(old_a, b), Err(err));
1094				},
1095			}
1096		}
1097	}
1098
1099	/// Generates some good values for testing integer arithmetic.
1100	fn values() -> Vec<(i32, i32)> {
1101		let mut rng = thread_rng();
1102		let mut one_dimension = || {
1103			let mut ret = vec![0i32; 1007];
1104			// Some hard-coded interesting values.
1105			ret[..7].copy_from_slice(&[-1, 0, 1, i32::MIN, i32::MAX, i32::MAX - 1, i32::MIN + 1]);
1106			// … and some random ones.
1107			rng.fill(&mut ret[7..]);
1108			ret.shuffle(&mut rng);
1109			ret
1110		};
1111		one_dimension().into_iter().zip(one_dimension().into_iter()).collect()
1112	}
1113}