Skip to content

Commit 65b7eea

Browse files
authored
Merge pull request #2729 from dtolnay/saturating
Integrate Saturating<T> deserialization into impl_deserialize_num macro
2 parents c13b3f7 + 01cd696 commit 65b7eea

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy