use std::fmt;
use std::str::FromStr;
use serde::de;
mod internal;
use internal::{
DisplayInteger,
IntegerVisitor,
ParsedInteger,
};
fn parse_canonical_integer<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 128-bit integer string"));
}
Ok(parsed)
}
macro_rules! define_wide_integer_serde {
($scalar_module:ident, $vector_module:ident, $type:ty) => {
pub(crate) mod $scalar_module {
use std::marker::PhantomData;
use serde::{
Deserializer,
Serialize,
Serializer,
};
use super::{
DisplayInteger,
IntegerVisitor,
};
pub(crate) fn serialize<S>(
value: &$type,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
DisplayInteger(value).serialize(serializer)
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<$type, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(IntegerVisitor(PhantomData))
}
}
pub(crate) mod $vector_module {
use serde::{
Deserialize,
Deserializer,
Serializer,
};
use super::{
DisplayInteger,
ParsedInteger,
};
pub(crate) fn serialize<S>(
values: &[$type],
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_seq(values.iter().map(DisplayInteger))
}
pub(crate) fn deserialize<'de, D>(
deserializer: D,
) -> Result<Vec<$type>, D::Error>
where
D: Deserializer<'de>,
{
Vec::<ParsedInteger<$type>>::deserialize(deserializer).map(
|values| values.into_iter().map(|value| value.0).collect(),
)
}
}
};
}
define_wide_integer_serde!(int128, int128_vec, i128);
define_wide_integer_serde!(uint128, uint128_vec, u128);