// This file is part of Substrate.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//! Types that implement [`PerThing`](PerThing) can be used as a floating-point alternative for
//! numbers that operate within the realm of `[0, 1]`. The primary types may you encounter in
//! Substrate would be the following:
//! - [`Percent`](Percent) - parts of one hundred.
//! - [`Permill`](Permill) - parts of a million.
//! - [`Perbill`](Perbill) - parts of a billion.
//!
//! In use, you may see them being used as follows:
//!
//! > **[`Perbill`](Perbill), parts of a billion**
#![doc = docify::embed!("./src/lib.rs", perbill_example)]
//! > **[`Percent`](Percent), parts of a hundred**
#![doc = docify::embed!("./src/lib.rs", percent_example)]
//!
//! Note that `Percent` is represented as a _rounded down_, fixed point
//! number (see the example above). Unlike primitive types, types that implement
//! [`PerThing`](PerThing) will also not overflow, and are therefore safe to use.
//! They adopt the same behavior that a saturated calculation would provide, meaning that if one is
//! to go over "100%", it wouldn't overflow, but simply stop at the upper or lower bound.
//!
//! For use cases which require precision beyond the range of `[0, 1]`, there are fixed-point types
//! which can be used.
//!
//! Each of these can be used to construct and represent ratios within our runtime.
//! You will find types like [`Perbill`](Perbill) being used often in pallet
//! development. `pallet_referenda` is a good example of a pallet which makes good use of fixed
//! point arithmetic, as it relies on representing various curves and thresholds relating to
//! governance.
//!
//! #### Fixed Point Arithmetic with [`PerThing`](PerThing)
//!
//! As stated, one can also perform mathematics using these types directly. For example, finding the
//! percentage of a particular item:
#![doc = docify::embed!("./src/lib.rs", percent_mult)]
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::traits::{
BaseArithmetic, Bounded, CheckedAdd, CheckedMul, CheckedSub, One, SaturatedConversion,
Saturating, UniqueSaturatedInto, Unsigned, Zero,
};
use codec::{CompactAs, Encode};
use core::{
fmt, ops,
ops::{Add, Sub},
};
use num_traits::{Pow, SaturatingAdd, SaturatingSub};
/// Get the inner type of a `PerThing`.
pub type InnerOf
=
::Inner;
/// Get the upper type of a `PerThing`.
pub type UpperOf
=
::Upper;
pub trait RationalArg:
Clone
+ Ord
+ ops::Div
+ ops::Rem
+ ops::Add
+ ops::AddAssign
+ Unsigned
+ Zero
+ One
+ crate::MultiplyRational
{
}
impl<
T: Clone
+ Ord
+ ops::Div
+ ops::Rem
+ ops::Add
+ ops::AddAssign
+ Unsigned
+ Zero
+ One
+ crate::MultiplyRational,
> RationalArg for T
{
}
pub trait MultiplyArg:
Clone
+ ops::Rem
+ ops::Div
+ ops::Mul
+ ops::Add
+ Unsigned
{
}
impl<
T: Clone
+ ops::Rem
+ ops::Div
+ ops::Mul
+ ops::Add
+ Unsigned,
> MultiplyArg for T
{
}
pub trait ReciprocalArg: MultiplyArg + Saturating {}
impl ReciprocalArg for T {}
/// Something that implements a fixed point ration with an arbitrary granularity `X`, as _parts per
/// `X`_.
pub trait PerThing:
Sized
+ Saturating
+ Copy
+ Default
+ Eq
+ PartialEq
+ Ord
+ PartialOrd
+ Bounded
+ fmt::Debug
+ ops::Div