use candid::CandidType;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::ops::{Add, AddAssign, Sub, SubAssign};
mod test;
#[derive(CandidType, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct ICPToken {
pub e8s: u64,
}
impl ICPToken {
pub const DECIMALS: u8 = 8;
pub const MAX: Self = ICPToken { e8s: u64::MAX };
pub const ZERO: Self = ICPToken { e8s: 0 };
pub const SUBDIVIDABLE_BY: u64 = 100_000_000;
pub const fn from_e8s(e8s: u64) -> Self {
Self { e8s }
}
pub const fn e8s(&self) -> u64 {
self.e8s
}
pub const fn amount(&self) -> u64 {
self.e8s / Self::SUBDIVIDABLE_BY
}
pub const fn is_zero(&self) -> bool {
self.e8s == 0
}
}
impl Add for ICPToken {
type Output = Self;
fn add(self, other: Self) -> Self {
let e8s = self.e8s.checked_add(other.e8s).unwrap_or_else(|| {
panic!(
"Add Tokens {} + {} failed because the underlying u64 overflowed",
self.e8s, other.e8s
)
});
Self { e8s }
}
}
impl AddAssign for ICPToken {
fn add_assign(&mut self, other: Self) {
let temp = self.clone() + other;
*self = temp;
}
}
impl Sub for ICPToken {
type Output = Self;
fn sub(self, other: Self) -> Self {
let e8s = self.e8s.checked_sub(other.e8s).unwrap_or_else(|| {
panic!(
"Subtracting Tokens {} - {} failed because the underlying u64 underflowed",
self.e8s, other.e8s
)
});
Self { e8s }
}
}
impl SubAssign for ICPToken {
fn sub_assign(&mut self, other: Self) {
let temp = self.clone() - other;
*self = temp;
}
}
impl fmt::Display for ICPToken {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}.{:08}",
self.e8s / ICPToken::SUBDIVIDABLE_BY,
self.e8s % ICPToken::SUBDIVIDABLE_BY
)
}
}