use crate::{ParseDecimalError, ParseError};
use core::str::FromStr;
#[cfg(feature = "rust_decimal")]
use rust_decimal::prelude::{FromPrimitive, ToPrimitive};
pub type Integer = i128;
pub type Long = i64;
pub type Int = i32;
pub type Short = i16;
pub type Byte = i8;
#[cfg(feature = "rust_decimal")]
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(
feature = "borsh",
derive(borsh::BorshSerialize, borsh::BorshDeserialize)
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Decimal(
#[cfg_attr(feature = "serde", serde(with = "rust_decimal::serde::str"))] rust_decimal::Decimal,
);
#[cfg(not(feature = "rust_decimal"))]
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Decimal(crate::primitive::Double);
impl Decimal {
pub fn is_integer(&self) -> bool {
#[cfg(feature = "rust_decimal")]
return self.0.is_integer();
#[cfg(not(feature = "rust_decimal"))]
return self.0.as_f64().fract() == 0.0;
}
pub fn as_f64(&self) -> f64 {
return self.0.as_f64();
}
pub fn to_f64(&self) -> Option<f64> {
Some(self.as_f64())
}
pub fn to_i128(&self) -> Option<i128> {
if !self.is_integer() {
return None;
}
#[cfg(feature = "rust_decimal")]
return self.0.to_i128();
#[cfg(not(feature = "rust_decimal"))]
return Some(self.as_f64() as i128);
}
#[cfg(feature = "serde")]
pub fn to_json(&self) -> Option<serde_json::Value> {
Some(self.clone().into_json())
}
#[cfg(feature = "serde")]
pub fn into_json(self) -> serde_json::Value {
use alloc::string::ToString;
serde_json::Value::String(self.to_string())
}
}
impl core::fmt::Display for Decimal {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
self.0.fmt(f)
}
}
impl From<i8> for Decimal {
fn from(input: i8) -> Self {
Self(input.into())
}
}
impl From<i16> for Decimal {
fn from(input: i16) -> Self {
Self(input.into())
}
}
impl From<i32> for Decimal {
fn from(input: i32) -> Self {
Self(input.into())
}
}
impl From<i64> for Decimal {
fn from(input: i64) -> Self {
Self(input.into())
}
}
impl From<i128> for Decimal {
fn from(input: i128) -> Self {
Self(input.into())
}
}
impl From<isize> for Decimal {
fn from(input: isize) -> Self {
Self(input.into())
}
}
#[cfg(feature = "rust_decimal")]
impl From<rust_decimal::Decimal> for Decimal {
fn from(input: rust_decimal::Decimal) -> Self {
Self(input)
}
}
#[cfg(feature = "rust_decimal")]
impl From<&rust_decimal::Decimal> for Decimal {
fn from(input: &rust_decimal::Decimal) -> Self {
Self(input.clone())
}
}
impl FromStr for Decimal {
type Err = ParseDecimalError;
#[cfg(feature = "rust_decimal")]
fn from_str(input: &str) -> Result<Self, Self::Err> {
Ok(Self(input.parse::<rust_decimal::Decimal>()?))
}
#[cfg(not(feature = "rust_decimal"))]
fn from_str(input: &str) -> Result<Self, Self::Err> {
input
.parse::<crate::primitive::Double>()
.map(Self)
.map_err(|_| ParseDecimalError)
}
}
impl TryFrom<f32> for Decimal {
type Error = ParseDecimalError;
#[cfg(feature = "rust_decimal")]
fn try_from(input: f32) -> Result<Self, Self::Error> {
Ok(Self(rust_decimal::Decimal::try_from(input)?))
}
#[cfg(not(feature = "rust_decimal"))]
fn try_from(input: f32) -> Result<Self, Self::Error> {
Ok(Self(input.into()))
}
}
impl TryFrom<f64> for Decimal {
type Error = ParseDecimalError;
#[cfg(feature = "rust_decimal")]
fn try_from(input: f64) -> Result<Self, Self::Error> {
Ok(Self(rust_decimal::Decimal::try_from(input)?))
}
#[cfg(not(feature = "rust_decimal"))]
fn try_from(input: f64) -> Result<Self, Self::Error> {
Ok(Self(input.into()))
}
}
impl TryFrom<Decimal> for i128 {
type Error = ();
fn try_from(input: Decimal) -> Result<Self, Self::Error> {
Self::try_from(&input)
}
}
impl TryFrom<&Decimal> for i128 {
type Error = ();
fn try_from(input: &Decimal) -> Result<Self, Self::Error> {
input.to_i128().ok_or(())
}
}