use std::fmt;
use std::marker::PhantomData;
use std::str::FromStr;
use serde::de;
use serde::{
Deserialize,
Deserializer,
Serialize,
Serializer,
};
mod internal;
use internal::{
DecimalVisitor,
DisplayDecimal,
ParsedDecimal,
};
fn parse_canonical_decimal<T, E>(value: &str) -> Result<T, E>
where
T: FromStr + fmt::Display,
T::Err: fmt::Display,
E: de::Error,
{
let parsed = value.parse::<T>().map_err(E::custom)?;
if parsed.to_string() != value {
return Err(E::custom("non-canonical decimal string"));
}
Ok(parsed)
}
pub(super) fn serialize<T, S>(
value: &T,
serializer: S,
) -> Result<S::Ok, S::Error>
where
T: fmt::Display,
S: Serializer,
{
DisplayDecimal(value).serialize(serializer)
}
pub(super) fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: FromStr + fmt::Display,
T::Err: fmt::Display,
D: Deserializer<'de>,
{
deserializer.deserialize_str(DecimalVisitor(PhantomData))
}
pub(super) fn serialize_vec<T, S>(
values: &[T],
serializer: S,
) -> Result<S::Ok, S::Error>
where
T: fmt::Display,
S: Serializer,
{
serializer.collect_seq(values.iter().map(DisplayDecimal))
}
pub(super) fn deserialize_vec<'de, T, D>(
deserializer: D,
) -> Result<Vec<T>, D::Error>
where
T: FromStr + fmt::Display,
T::Err: fmt::Display,
D: Deserializer<'de>,
{
Vec::<ParsedDecimal<T>>::deserialize(deserializer)
.map(|values| values.into_iter().map(|value| value.0).collect())
}