use derive_more::{Display, From, Into};
use serde::{Deserialize, Serialize};
use std::iter::Sum;
use std::ops::Add;
use std::str::FromStr;
use super::error::Error;
use crate::bigint::U256;
#[derive(
Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize, Display, From, Into,
)]
pub struct Amount(pub U256);
impl Amount {
pub fn checked_add(self, rhs: impl Into<Amount>) -> Option<Self> {
self.0.checked_add(rhs.into().0).map(Self)
}
pub fn checked_sub(self, rhs: impl Into<Amount>) -> Option<Self> {
self.0.checked_sub(rhs.into().0).map(Self)
}
}
impl Add for Amount {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl Sum for Amount {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Self(U256::from(0)), |a, b| a + b)
}
}
impl FromStr for Amount {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let amount = U256::from_dec_str(s).map_err(Error::invalid_amount)?;
Ok(Self(amount))
}
}
impl From<u64> for Amount {
fn from(v: u64) -> Self {
Self(v.into())
}
}
impl From<u128> for Amount {
fn from(amount: u128) -> Self {
Self(amount.into())
}
}