mirror of
https://github.com/serde-rs/serde.git
synced 2025-10-02 07:21:12 +00:00
Integrate Saturating<T> deserialization into impl_deserialize_num macro
This commit is contained in:
parent
c13b3f7e68
commit
01cd696fd1
@ -104,6 +104,28 @@ macro_rules! impl_deserialize_num {
|
|||||||
deserializer.$deserialize(NonZeroVisitor)
|
deserializer.$deserialize(NonZeroVisitor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(no_core_num_saturating))]
|
||||||
|
impl<'de> Deserialize<'de> for Saturating<$primitive> {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct SaturatingVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for SaturatingVisitor {
|
||||||
|
type Value = Saturating<$primitive>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("integer with support for saturating semantics")
|
||||||
|
}
|
||||||
|
|
||||||
|
$($($method!(saturating $primitive $val : $visit);)*)*
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.$deserialize(SaturatingVisitor)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
|
($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
|
||||||
@ -154,6 +176,15 @@ macro_rules! num_self {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(saturating $primitive:ident $ty:ident : $visit:ident) => {
|
||||||
|
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
Ok(Saturating(v))
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! num_as_self {
|
macro_rules! num_as_self {
|
||||||
@ -179,6 +210,15 @@ macro_rules! num_as_self {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(saturating $primitive:ident $ty:ident : $visit:ident) => {
|
||||||
|
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
Ok(Saturating(v as $primitive))
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! num_as_copysign_self {
|
macro_rules! num_as_copysign_self {
|
||||||
@ -235,6 +275,21 @@ macro_rules! int_to_int {
|
|||||||
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
|
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(saturating $primitive:ident $ty:ident : $visit:ident) => {
|
||||||
|
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
if (v as i64) < $primitive::MIN as i64 {
|
||||||
|
Ok(Saturating($primitive::MIN))
|
||||||
|
} else if ($primitive::MAX as i64) < v as i64 {
|
||||||
|
Ok(Saturating($primitive::MAX))
|
||||||
|
} else {
|
||||||
|
Ok(Saturating(v as $primitive))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! int_to_uint {
|
macro_rules! int_to_uint {
|
||||||
@ -265,6 +320,21 @@ macro_rules! int_to_uint {
|
|||||||
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
|
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(saturating $primitive:ident $ty:ident : $visit:ident) => {
|
||||||
|
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
if v < 0 {
|
||||||
|
Ok(Saturating(0))
|
||||||
|
} else if ($primitive::MAX as u64) < v as u64 {
|
||||||
|
Ok(Saturating($primitive::MAX))
|
||||||
|
} else {
|
||||||
|
Ok(Saturating(v as $primitive))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! uint_to_self {
|
macro_rules! uint_to_self {
|
||||||
@ -295,6 +365,19 @@ macro_rules! uint_to_self {
|
|||||||
Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
|
Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(saturating $primitive:ident $ty:ident : $visit:ident) => {
|
||||||
|
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
if v as u64 <= $primitive::MAX as u64 {
|
||||||
|
Ok(Saturating(v as $primitive))
|
||||||
|
} else {
|
||||||
|
Ok(Saturating($primitive::MAX))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_deserialize_num! {
|
impl_deserialize_num! {
|
||||||
@ -387,73 +470,6 @@ impl_deserialize_num! {
|
|||||||
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
|
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(no_core_num_saturating))]
|
|
||||||
macro_rules! visit_saturating {
|
|
||||||
($primitive:ident, $ty:ident : $visit:ident) => {
|
|
||||||
#[inline]
|
|
||||||
fn $visit<E>(self, v: $ty) -> Result<Saturating<$primitive>, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
let out: $primitive = core::convert::TryFrom::<$ty>::try_from(v).unwrap_or_else(|_| {
|
|
||||||
#[allow(unused_comparisons)]
|
|
||||||
if v < 0 {
|
|
||||||
// never true for unsigned values
|
|
||||||
$primitive::MIN
|
|
||||||
} else {
|
|
||||||
$primitive::MAX
|
|
||||||
}
|
|
||||||
});
|
|
||||||
Ok(Saturating(out))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! impl_deserialize_saturating_num {
|
|
||||||
($primitive:ident, $deserialize:ident) => {
|
|
||||||
#[cfg(not(no_core_num_saturating))]
|
|
||||||
impl<'de> Deserialize<'de> for Saturating<$primitive> {
|
|
||||||
#[inline]
|
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
struct SaturatingVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for SaturatingVisitor {
|
|
||||||
type Value = Saturating<$primitive>;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("integer with support for saturating semantics")
|
|
||||||
}
|
|
||||||
|
|
||||||
visit_saturating!($primitive, u8:visit_u8);
|
|
||||||
visit_saturating!($primitive, u16:visit_u16);
|
|
||||||
visit_saturating!($primitive, u32:visit_u32);
|
|
||||||
visit_saturating!($primitive, u64:visit_u64);
|
|
||||||
visit_saturating!($primitive, i8:visit_i8);
|
|
||||||
visit_saturating!($primitive, i16:visit_i16);
|
|
||||||
visit_saturating!($primitive, i32:visit_i32);
|
|
||||||
visit_saturating!($primitive, i64:visit_i64);
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.$deserialize(SaturatingVisitor)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_deserialize_saturating_num!(u8, deserialize_u8);
|
|
||||||
impl_deserialize_saturating_num!(u16, deserialize_u16);
|
|
||||||
impl_deserialize_saturating_num!(u32, deserialize_u32);
|
|
||||||
impl_deserialize_saturating_num!(u64, deserialize_u64);
|
|
||||||
impl_deserialize_saturating_num!(usize, deserialize_u64);
|
|
||||||
impl_deserialize_saturating_num!(i8, deserialize_i8);
|
|
||||||
impl_deserialize_saturating_num!(i16, deserialize_i16);
|
|
||||||
impl_deserialize_saturating_num!(i32, deserialize_i32);
|
|
||||||
impl_deserialize_saturating_num!(i64, deserialize_i64);
|
|
||||||
impl_deserialize_saturating_num!(isize, deserialize_i64);
|
|
||||||
|
|
||||||
macro_rules! num_128 {
|
macro_rules! num_128 {
|
||||||
($ty:ident : $visit:ident) => {
|
($ty:ident : $visit:ident) => {
|
||||||
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
||||||
@ -494,6 +510,21 @@ macro_rules! num_128 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(saturating $primitive:ident $ty:ident : $visit:ident) => {
|
||||||
|
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
if (v as i128) < $primitive::MIN as i128 {
|
||||||
|
Ok(Saturating($primitive::MIN))
|
||||||
|
} else if ($primitive::MAX as u128) < v as u128 {
|
||||||
|
Ok(Saturating($primitive::MAX))
|
||||||
|
} else {
|
||||||
|
Ok(Saturating(v as $primitive))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_deserialize_num! {
|
impl_deserialize_num! {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user