mod error;
mod trait_impls;
mod utils;
pub use self::error::UncGasError;
pub use self::utils::DecimalNumberParsingError;
#[derive(Default, Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)]
#[cfg_attr(
feature = "borsh",
derive(borsh::BorshDeserialize, borsh::BorshSerialize)
)]
#[cfg_attr(feature = "abi", derive(borsh::BorshSchema))]
#[repr(transparent)]
pub struct UncGas {
inner: u64,
}
const ONE_TERA_GAS: u64 = 10u64.pow(12);
const ONE_GIGA_GAS: u64 = 10u64.pow(9);
impl UncGas {
pub const fn from_tgas(mut inner: u64) -> Self {
inner *= ONE_TERA_GAS;
Self { inner }
}
pub const fn from_ggas(mut inner: u64) -> Self {
inner *= ONE_GIGA_GAS;
Self { inner }
}
pub const fn from_gas(inner: u64) -> Self {
Self { inner }
}
pub const fn as_gas(self) -> u64 {
self.inner
}
pub const fn as_ggas(self) -> u64 {
self.inner / ONE_GIGA_GAS
}
pub const fn as_tgas(self) -> u64 {
self.inner / ONE_TERA_GAS
}
pub const fn checked_add(self, rhs: UncGas) -> Option<Self> {
if let Some(gas) = self.as_gas().checked_add(rhs.as_gas()) {
Some(Self::from_gas(gas))
} else {
None
}
}
pub const fn checked_sub(self, rhs: UncGas) -> Option<Self> {
if let Some(gas) = self.as_gas().checked_sub(rhs.as_gas()) {
Some(Self::from_gas(gas))
} else {
None
}
}
pub const fn checked_mul(self, rhs: u64) -> Option<Self> {
if let Some(gas) = self.as_gas().checked_mul(rhs) {
Some(Self::from_gas(gas))
} else {
None
}
}
pub const fn checked_div(self, rhs: u64) -> Option<Self> {
if let Some(gas) = self.as_gas().checked_div(rhs) {
Some(Self::from_gas(gas))
} else {
None
}
}
pub const fn saturating_add(self, rhs: UncGas) -> UncGas {
UncGas::from_gas(self.as_gas().saturating_add(rhs.as_gas()))
}
pub const fn saturating_sub(self, rhs: UncGas) -> UncGas {
UncGas::from_gas(self.as_gas().saturating_sub(rhs.as_gas()))
}
pub const fn saturating_mul(self, rhs: u64) -> UncGas {
UncGas::from_gas(self.as_gas().saturating_mul(rhs))
}
pub const fn saturating_div(self, rhs: u64) -> UncGas {
if rhs == 0 {
return UncGas::from_gas(0);
}
UncGas::from_gas(self.as_gas().saturating_div(rhs))
}
}
#[cfg(test)]
mod test {
use crate::UncGas;
#[test]
fn checked_add_gas() {
let gas = UncGas::from_gas(u64::MAX - 3);
let any_gas = UncGas::from_gas(3);
let more_gas = UncGas::from_gas(4);
assert_eq!(gas.checked_add(any_gas), Some(UncGas::from_gas(u64::MAX)));
assert_eq!(gas.checked_add(more_gas), None);
}
#[test]
fn checked_sub_gas() {
let gas = UncGas::from_gas(3);
let any_gas = UncGas::from_gas(1);
let more_gas = UncGas::from_gas(4);
assert_eq!(gas.checked_sub(any_gas), Some(UncGas::from_gas(2)));
assert_eq!(gas.checked_sub(more_gas), None);
}
#[test]
fn checked_mul_gas() {
let gas = UncGas::from_gas(u64::MAX / 10);
assert_eq!(
gas.checked_mul(10),
Some(UncGas::from_gas(u64::MAX / 10 * 10))
);
assert_eq!(gas.checked_mul(11), None);
}
#[test]
fn checked_div_gas() {
let gas = UncGas::from_gas(10);
assert_eq!(gas.checked_div(2), Some(UncGas::from_gas(5)));
assert_eq!(gas.checked_div(11), Some(UncGas::from_gas(0)));
assert_eq!(gas.checked_div(0), None);
}
#[test]
fn saturating_add_gas() {
let gas = UncGas::from_gas(100);
let added_gas = UncGas::from_gas(1);
let another_gas = UncGas::from_gas(u64::MAX);
assert_eq!(
gas.saturating_add(added_gas.clone()),
UncGas::from_gas(101)
);
assert_eq!(
another_gas.saturating_add(added_gas),
UncGas::from_gas(u64::MAX)
);
}
#[test]
fn saturating_sub_gas() {
let gas = UncGas::from_gas(100);
let rhs_gas = UncGas::from_gas(1);
let another_gas = UncGas::from_gas(u64::MIN);
assert_eq!(gas.saturating_sub(rhs_gas.clone()), UncGas::from_gas(99));
assert_eq!(
another_gas.saturating_sub(rhs_gas),
UncGas::from_gas(u64::MIN)
);
}
#[test]
fn saturating_mul_gas() {
let gas = UncGas::from_gas(2);
let rhs = 10;
let another_gas = u64::MAX;
assert_eq!(gas.saturating_mul(rhs), UncGas::from_gas(20));
assert_eq!(gas.saturating_mul(another_gas), UncGas::from_gas(u64::MAX));
}
#[test]
fn saturating_div_gas() {
let gas = UncGas::from_gas(10);
let rhs = 2;
let another_gas = 20;
assert_eq!(gas.saturating_div(rhs), UncGas::from_gas(5));
assert_eq!(gas.saturating_div(another_gas), UncGas::from_gas(0));
}
}