use std::str::FromStr;
use serde::de::Error;
use serde::Deserializer;
use crate::big_decimal_json::ser::BigDecimalJsonWrap;
use crate::decimal::BigDecimal;
use crate::decimal::ToPrimitive;
#[derive(Debug, Clone)]
pub struct BigDecimalJson(BigDecimal);
pub mod ser {
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
pub struct BigDecimalJsonWrap {
pub decimal: String,
pub rounded: Option<f64>,
}
}
impl serde::Serialize for BigDecimalJson {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer, {
let exact_value = self.0.to_string();
let rounded_value = self.0.to_f64();
let json_struct = BigDecimalJsonWrap { decimal: exact_value, rounded: rounded_value };
serializer.serialize_some(&json_struct)
}
}
impl<'de> serde::Deserialize<'de> for BigDecimalJson {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = serde_json::Value::deserialize(deserializer)?;
let result = match &value {
serde_json::Value::Object(object) => {
if let Some(decimal) = object.get("decimal").and_then(|value| value.as_str()) {
let bigdecimal_result = BigDecimal::from_str(decimal).map_err(|err| D::Error::custom(err));
bigdecimal_result.map(|bigdecimal| BigDecimalJson(bigdecimal))
} else {
Err(Error::custom(format_args!(
"`decimal` is not present` {}, expected {}",
value, "&str"
)))
}
}
_ => Err(Error::custom(format_args!(
"invalid type for value {}, expected {}",
value, "array"
))),
};
result
}
}
impl From<BigDecimal> for BigDecimalJson {
fn from(value: BigDecimal) -> Self {
BigDecimalJson(value)
}
}
impl From<&BigDecimal> for BigDecimalJson {
fn from(value: &BigDecimal) -> Self {
BigDecimalJson(value.clone())
}
}
impl Into<BigDecimal> for BigDecimalJson {
fn into(self) -> BigDecimal {
self.0
}
}