use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "fastnum")]
pub mod fastnum {
use super::*;
#[cfg(feature = "fastnum")]
use ::fastnum::{
bint::UInt,
decimal::{Context, Decimal as FastnumDecimal, Sign},
};
use serde::de::Error as _;
pub struct Decimal<const E: i16, const S: usize>;
#[cfg(feature = "fastnum")]
impl<const DECIMAL_PLACE: i16, const N: usize> Decimal<DECIMAL_PLACE, N> {
pub fn deserialize<'de, D>(deserializer: D) -> Result<FastnumDecimal<N>, D::Error>
where
D: Deserializer<'de>,
{
let bytes: [u8; 32] = Deserialize::deserialize(deserializer)?;
let mut uint = UInt::from_radix_le(&bytes, 256)
.ok_or(D::Error::custom("failed to deserialize uint from bytes"))?;
uint /= UInt::from_u16(10u16).pow((DECIMAL_PLACE as u16).into());
let value = FastnumDecimal::from_parts(
UInt::from_le(uint),
-DECIMAL_PLACE as i32,
Sign::Plus,
Context::default(),
);
Ok(value)
}
pub fn serialize<S: Serializer>(
value: &FastnumDecimal<N>,
serializer: S,
) -> Result<S::Ok, S::Error> {
let mut value = value.rescale(DECIMAL_PLACE);
value *= FastnumDecimal::from_u16(10u16).pow((DECIMAL_PLACE as u16).into());
let mut digits_le: Vec<u8> = value.digits().to_radix_le(256);
let padding_bytes = vec![0; 32 - digits_le.len()];
digits_le.extend(padding_bytes);
let exact_bytes: [u8; 32] = digits_le.try_into().unwrap();
exact_bytes.serialize(serializer)
}
}
}
pub mod map {
use std::collections::HashMap;
use super::*;
pub fn serialize<S: Serializer>(
value: &HashMap<String, String>,
serializer: S,
) -> Result<S::Ok, S::Error> {
let value: Vec<(String, String)> = value.clone().into_iter().collect();
value.serialize(serializer)
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<HashMap<String, String>, D::Error>
where
D: Deserializer<'de>,
{
let value: Vec<(String, String)> = Deserialize::deserialize(deserializer)?;
Ok(value.into_iter().collect())
}
}