Skip to content

Commit 01cd696

Browse files
committed
Integrate Saturating<T> deserialization into impl_deserialize_num macro
1 parent c13b3f7 commit 01cd696

File tree

1 file changed

+98
-67
lines changed

1 file changed

+98
-67
lines changed

serde/src/de/impls.rs

Lines changed: 98 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,28 @@ macro_rules! impl_deserialize_num {
104104
deserializer.$deserialize(NonZeroVisitor)
105105
}
106106
}
107+
108+
#[cfg(not(no_core_num_saturating))]
109+
impl<'de> Deserialize<'de> for Saturating<$primitive> {
110+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
111+
where
112+
D: Deserializer<'de>,
113+
{
114+
struct SaturatingVisitor;
115+
116+
impl<'de> Visitor<'de> for SaturatingVisitor {
117+
type Value = Saturating<$primitive>;
118+
119+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
120+
formatter.write_str("integer with support for saturating semantics")
121+
}
122+
123+
$($($method!(saturating $primitive $val : $visit);)*)*
124+
}
125+
126+
deserializer.$deserialize(SaturatingVisitor)
127+
}
128+
}
107129
};
108130

109131
($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
@@ -154,6 +176,15 @@ macro_rules! num_self {
154176
}
155177
}
156178
};
179+
180+
(saturating $primitive:ident $ty:ident : $visit:ident) => {
181+
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
182+
where
183+
E: Error,
184+
{
185+
Ok(Saturating(v))
186+
}
187+
};
157188
}
158189

159190
macro_rules! num_as_self {
@@ -179,6 +210,15 @@ macro_rules! num_as_self {
179210
}
180211
}
181212
};
213+
214+
(saturating $primitive:ident $ty:ident : $visit:ident) => {
215+
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
216+
where
217+
E: Error,
218+
{
219+
Ok(Saturating(v as $primitive))
220+
}
221+
};
182222
}
183223

184224
macro_rules! num_as_copysign_self {
@@ -235,6 +275,21 @@ macro_rules! int_to_int {
235275
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
236276
}
237277
};
278+
279+
(saturating $primitive:ident $ty:ident : $visit:ident) => {
280+
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
281+
where
282+
E: Error,
283+
{
284+
if (v as i64) < $primitive::MIN as i64 {
285+
Ok(Saturating($primitive::MIN))
286+
} else if ($primitive::MAX as i64) < v as i64 {
287+
Ok(Saturating($primitive::MAX))
288+
} else {
289+
Ok(Saturating(v as $primitive))
290+
}
291+
}
292+
};
238293
}
239294

240295
macro_rules! int_to_uint {
@@ -265,6 +320,21 @@ macro_rules! int_to_uint {
265320
Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
266321
}
267322
};
323+
324+
(saturating $primitive:ident $ty:ident : $visit:ident) => {
325+
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
326+
where
327+
E: Error,
328+
{
329+
if v < 0 {
330+
Ok(Saturating(0))
331+
} else if ($primitive::MAX as u64) < v as u64 {
332+
Ok(Saturating($primitive::MAX))
333+
} else {
334+
Ok(Saturating(v as $primitive))
335+
}
336+
}
337+
};
268338
}
269339

270340
macro_rules! uint_to_self {
@@ -295,6 +365,19 @@ macro_rules! uint_to_self {
295365
Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
296366
}
297367
};
368+
369+
(saturating $primitive:ident $ty:ident : $visit:ident) => {
370+
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
371+
where
372+
E: Error,
373+
{
374+
if v as u64 <= $primitive::MAX as u64 {
375+
Ok(Saturating(v as $primitive))
376+
} else {
377+
Ok(Saturating($primitive::MAX))
378+
}
379+
}
380+
};
298381
}
299382

300383
impl_deserialize_num! {
@@ -387,73 +470,6 @@ impl_deserialize_num! {
387470
num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
388471
}
389472

390-
#[cfg(not(no_core_num_saturating))]
391-
macro_rules! visit_saturating {
392-
($primitive:ident, $ty:ident : $visit:ident) => {
393-
#[inline]
394-
fn $visit<E>(self, v: $ty) -> Result<Saturating<$primitive>, E>
395-
where
396-
E: Error,
397-
{
398-
let out: $primitive = core::convert::TryFrom::<$ty>::try_from(v).unwrap_or_else(|_| {
399-
#[allow(unused_comparisons)]
400-
if v < 0 {
401-
// never true for unsigned values
402-
$primitive::MIN
403-
} else {
404-
$primitive::MAX
405-
}
406-
});
407-
Ok(Saturating(out))
408-
}
409-
};
410-
}
411-
412-
macro_rules! impl_deserialize_saturating_num {
413-
($primitive:ident, $deserialize:ident) => {
414-
#[cfg(not(no_core_num_saturating))]
415-
impl<'de> Deserialize<'de> for Saturating<$primitive> {
416-
#[inline]
417-
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
418-
where
419-
D: Deserializer<'de>,
420-
{
421-
struct SaturatingVisitor;
422-
423-
impl<'de> Visitor<'de> for SaturatingVisitor {
424-
type Value = Saturating<$primitive>;
425-
426-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
427-
formatter.write_str("integer with support for saturating semantics")
428-
}
429-
430-
visit_saturating!($primitive, u8:visit_u8);
431-
visit_saturating!($primitive, u16:visit_u16);
432-
visit_saturating!($primitive, u32:visit_u32);
433-
visit_saturating!($primitive, u64:visit_u64);
434-
visit_saturating!($primitive, i8:visit_i8);
435-
visit_saturating!($primitive, i16:visit_i16);
436-
visit_saturating!($primitive, i32:visit_i32);
437-
visit_saturating!($primitive, i64:visit_i64);
438-
}
439-
440-
deserializer.$deserialize(SaturatingVisitor)
441-
}
442-
}
443-
};
444-
}
445-
446-
impl_deserialize_saturating_num!(u8, deserialize_u8);
447-
impl_deserialize_saturating_num!(u16, deserialize_u16);
448-
impl_deserialize_saturating_num!(u32, deserialize_u32);
449-
impl_deserialize_saturating_num!(u64, deserialize_u64);
450-
impl_deserialize_saturating_num!(usize, deserialize_u64);
451-
impl_deserialize_saturating_num!(i8, deserialize_i8);
452-
impl_deserialize_saturating_num!(i16, deserialize_i16);
453-
impl_deserialize_saturating_num!(i32, deserialize_i32);
454-
impl_deserialize_saturating_num!(i64, deserialize_i64);
455-
impl_deserialize_saturating_num!(isize, deserialize_i64);
456-
457473
macro_rules! num_128 {
458474
($ty:ident : $visit:ident) => {
459475
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
@@ -494,6 +510,21 @@ macro_rules! num_128 {
494510
}
495511
}
496512
};
513+
514+
(saturating $primitive:ident $ty:ident : $visit:ident) => {
515+
fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
516+
where
517+
E: Error,
518+
{
519+
if (v as i128) < $primitive::MIN as i128 {
520+
Ok(Saturating($primitive::MIN))
521+
} else if ($primitive::MAX as u128) < v as u128 {
522+
Ok(Saturating($primitive::MAX))
523+
} else {
524+
Ok(Saturating(v as $primitive))
525+
}
526+
}
527+
};
497528
}
498529

499530
impl_deserialize_num! {

0 commit comments

Comments
 (0)