Skip to content

Commit 0580b99

Browse files
authored
Merge pull request #2258 from CosmWasm/aw/deduplicate-serde-impl
Deduplicate serde impls for integers
2 parents 1f181c1 + 562a9a7 commit 0580b99

File tree

9 files changed

+63
-311
lines changed

9 files changed

+63
-311
lines changed

packages/std/src/math/int128.rs

+2-38
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use core::ops::{
55
ShrAssign, Sub, SubAssign,
66
};
77
use core::str::FromStr;
8-
use serde::{de, ser, Deserialize, Deserializer, Serialize};
98

109
use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError};
1110
use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
@@ -15,6 +14,7 @@ use crate::{
1514
};
1615

1716
use super::conversion::{forward_try_from, try_from_int_to_int};
17+
use super::impl_int_serde;
1818
use super::num_consts::NumConsts;
1919

2020
/// An implementation of i128 that is using strings for JSON encoding/decoding,
@@ -33,6 +33,7 @@ use super::num_consts::NumConsts;
3333
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
3434
pub struct Int128(#[schemars(with = "String")] pub(crate) i128);
3535

36+
impl_int_serde!(Int128);
3637
forward_ref_partial_eq!(Int128, Int128);
3738

3839
impl Int128 {
@@ -537,43 +538,6 @@ impl ShlAssign<u32> for Int128 {
537538
}
538539
forward_ref_op_assign!(impl ShlAssign, shl_assign for Int128, u32);
539540

540-
impl Serialize for Int128 {
541-
/// Serializes as an integer string using base 10
542-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
543-
where
544-
S: ser::Serializer,
545-
{
546-
serializer.serialize_str(&self.to_string())
547-
}
548-
}
549-
550-
impl<'de> Deserialize<'de> for Int128 {
551-
/// Deserialized from an integer string using base 10
552-
fn deserialize<D>(deserializer: D) -> Result<Int128, D::Error>
553-
where
554-
D: Deserializer<'de>,
555-
{
556-
deserializer.deserialize_str(Int128Visitor)
557-
}
558-
}
559-
560-
struct Int128Visitor;
561-
562-
impl<'de> de::Visitor<'de> for Int128Visitor {
563-
type Value = Int128;
564-
565-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
566-
formatter.write_str("string-encoded integer")
567-
}
568-
569-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
570-
where
571-
E: de::Error,
572-
{
573-
Int128::try_from(v).map_err(|e| E::custom(format_args!("invalid Int128 '{v}' - {e}")))
574-
}
575-
}
576-
577541
impl<A> core::iter::Sum<A> for Int128
578542
where
579543
Self: Add<A, Output = Self>,

packages/std/src/math/int256.rs

+2-38
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use core::ops::{
55
ShrAssign, Sub, SubAssign,
66
};
77
use core::str::FromStr;
8-
use serde::{de, ser, Deserialize, Deserializer, Serialize};
98

109
use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError};
1110
use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
@@ -19,6 +18,7 @@ use crate::{
1918
use bnum::types::{I256, U256};
2019

2120
use super::conversion::{grow_be_int, try_from_int_to_int, try_from_uint_to_int};
21+
use super::impl_int_serde;
2222
use super::num_consts::NumConsts;
2323

2424
/// An implementation of i256 that is using strings for JSON encoding/decoding,
@@ -44,6 +44,7 @@ use super::num_consts::NumConsts;
4444
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
4545
pub struct Int256(#[schemars(with = "String")] pub(crate) I256);
4646

47+
impl_int_serde!(Int256);
4748
forward_ref_partial_eq!(Int256, Int256);
4849

4950
impl Int256 {
@@ -612,43 +613,6 @@ impl ShlAssign<u32> for Int256 {
612613
}
613614
forward_ref_op_assign!(impl ShlAssign, shl_assign for Int256, u32);
614615

615-
impl Serialize for Int256 {
616-
/// Serializes as an integer string using base 10
617-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
618-
where
619-
S: ser::Serializer,
620-
{
621-
serializer.serialize_str(&self.to_string())
622-
}
623-
}
624-
625-
impl<'de> Deserialize<'de> for Int256 {
626-
/// Deserialized from an integer string using base 10
627-
fn deserialize<D>(deserializer: D) -> Result<Int256, D::Error>
628-
where
629-
D: Deserializer<'de>,
630-
{
631-
deserializer.deserialize_str(Int256Visitor)
632-
}
633-
}
634-
635-
struct Int256Visitor;
636-
637-
impl<'de> de::Visitor<'de> for Int256Visitor {
638-
type Value = Int256;
639-
640-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
641-
formatter.write_str("string-encoded integer")
642-
}
643-
644-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
645-
where
646-
E: de::Error,
647-
{
648-
Int256::try_from(v).map_err(|e| E::custom(format_args!("invalid Int256 '{v}' - {e}")))
649-
}
650-
}
651-
652616
impl<A> core::iter::Sum<A> for Int256
653617
where
654618
Self: Add<A, Output = Self>,

packages/std/src/math/int512.rs

+2-38
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use core::ops::{
55
ShrAssign, Sub, SubAssign,
66
};
77
use core::str::FromStr;
8-
use serde::{de, ser, Deserialize, Deserializer, Serialize};
98

109
use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError};
1110
use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
@@ -18,6 +17,7 @@ use crate::{
1817
use bnum::types::{I512, U512};
1918

2019
use super::conversion::{grow_be_int, try_from_uint_to_int};
20+
use super::impl_int_serde;
2121
use super::num_consts::NumConsts;
2222

2323
/// An implementation of i512 that is using strings for JSON encoding/decoding,
@@ -47,6 +47,7 @@ use super::num_consts::NumConsts;
4747
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
4848
pub struct Int512(#[schemars(with = "String")] pub(crate) I512);
4949

50+
impl_int_serde!(Int512);
5051
forward_ref_partial_eq!(Int512, Int512);
5152

5253
impl Int512 {
@@ -611,43 +612,6 @@ impl ShlAssign<u32> for Int512 {
611612
}
612613
forward_ref_op_assign!(impl ShlAssign, shl_assign for Int512, u32);
613614

614-
impl Serialize for Int512 {
615-
/// Serializes as an integer string using base 10
616-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
617-
where
618-
S: ser::Serializer,
619-
{
620-
serializer.serialize_str(&self.to_string())
621-
}
622-
}
623-
624-
impl<'de> Deserialize<'de> for Int512 {
625-
/// Deserialized from an integer string using base 10
626-
fn deserialize<D>(deserializer: D) -> Result<Int512, D::Error>
627-
where
628-
D: Deserializer<'de>,
629-
{
630-
deserializer.deserialize_str(Int512Visitor)
631-
}
632-
}
633-
634-
struct Int512Visitor;
635-
636-
impl<'de> de::Visitor<'de> for Int512Visitor {
637-
type Value = Int512;
638-
639-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
640-
formatter.write_str("string-encoded integer")
641-
}
642-
643-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
644-
where
645-
E: de::Error,
646-
{
647-
Int512::try_from(v).map_err(|e| E::custom(format!("invalid Int512 '{v}' - {e}")))
648-
}
649-
}
650-
651615
impl<A> core::iter::Sum<A> for Int512
652616
where
653617
Self: Add<A, Output = Self>,

packages/std/src/math/int64.rs

+2-38
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use core::ops::{
55
ShrAssign, Sub, SubAssign,
66
};
77
use core::str::FromStr;
8-
use serde::{de, ser, Deserialize, Deserializer, Serialize};
98

109
use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError};
1110
use crate::forward_ref::{forward_ref_binop, forward_ref_op_assign};
@@ -15,6 +14,7 @@ use crate::{
1514
};
1615

1716
use super::conversion::{forward_try_from, try_from_int_to_int};
17+
use super::impl_int_serde;
1818
use super::num_consts::NumConsts;
1919

2020
/// An implementation of i64 that is using strings for JSON encoding/decoding,
@@ -33,6 +33,7 @@ use super::num_consts::NumConsts;
3333
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
3434
pub struct Int64(#[schemars(with = "String")] pub(crate) i64);
3535

36+
impl_int_serde!(Int64);
3637
forward_ref_partial_eq!(Int64, Int64);
3738

3839
impl Int64 {
@@ -516,43 +517,6 @@ impl ShlAssign<u32> for Int64 {
516517
}
517518
forward_ref_op_assign!(impl ShlAssign, shl_assign for Int64, u32);
518519

519-
impl Serialize for Int64 {
520-
/// Serializes as an integer string using base 10
521-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
522-
where
523-
S: ser::Serializer,
524-
{
525-
serializer.serialize_str(&self.to_string())
526-
}
527-
}
528-
529-
impl<'de> Deserialize<'de> for Int64 {
530-
/// Deserialized from an integer string using base 10
531-
fn deserialize<D>(deserializer: D) -> Result<Int64, D::Error>
532-
where
533-
D: Deserializer<'de>,
534-
{
535-
deserializer.deserialize_str(Int64Visitor)
536-
}
537-
}
538-
539-
struct Int64Visitor;
540-
541-
impl<'de> de::Visitor<'de> for Int64Visitor {
542-
type Value = Int64;
543-
544-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
545-
formatter.write_str("string-encoded integer")
546-
}
547-
548-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
549-
where
550-
E: de::Error,
551-
{
552-
Int64::try_from(v).map_err(|e| E::custom(format_args!("invalid Int64 '{v}' - {e}")))
553-
}
554-
}
555-
556520
impl<A> core::iter::Sum<A> for Int64
557521
where
558522
Self: Add<A, Output = Self>,

packages/std/src/math/mod.rs

+47
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,53 @@ pub use uint256::Uint256;
3030
pub use uint512::Uint512;
3131
pub use uint64::Uint64;
3232

33+
macro_rules! impl_int_serde {
34+
($ty:ty) => {
35+
impl ::serde::Serialize for $ty {
36+
/// Serializes as an integer string using base 10
37+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
38+
where
39+
S: ::serde::ser::Serializer,
40+
{
41+
serializer.serialize_str(&self.to_string())
42+
}
43+
}
44+
45+
impl<'de> ::serde::Deserialize<'de> for $ty {
46+
/// Deserialized from an integer string using base 10
47+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
48+
where
49+
D: ::serde::de::Deserializer<'de>,
50+
{
51+
struct IntVisitor;
52+
53+
impl<'de> ::serde::de::Visitor<'de> for IntVisitor {
54+
type Value = $ty;
55+
56+
fn expecting(
57+
&self,
58+
formatter: &mut ::core::fmt::Formatter,
59+
) -> ::core::fmt::Result {
60+
formatter.write_str("string-encoded integer")
61+
}
62+
63+
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
64+
where
65+
E: ::serde::de::Error,
66+
{
67+
<_>::try_from(v).map_err(|e| {
68+
E::custom(format_args!("invalid {} '{v}' - {e}", stringify!($t)))
69+
})
70+
}
71+
}
72+
73+
deserializer.deserialize_str(IntVisitor)
74+
}
75+
}
76+
};
77+
}
78+
use impl_int_serde;
79+
3380
#[cfg(test)]
3481
mod tests {
3582
use super::*;

packages/std/src/math/uint128.rs

+2-42
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ use core::ops::{
66
};
77
use core::str::FromStr;
88

9-
use serde::{de, ser, Deserialize, Deserializer, Serialize};
10-
119
use crate::errors::{
1210
CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError,
1311
OverflowOperation, StdError,
@@ -19,6 +17,7 @@ use crate::{
1917
};
2018

2119
use super::conversion::forward_try_from;
20+
use super::impl_int_serde;
2221
use super::num_consts::NumConsts;
2322

2423
/// A thin wrapper around u128 that is using strings for JSON encoding/decoding,
@@ -43,6 +42,7 @@ use super::num_consts::NumConsts;
4342
#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, schemars::JsonSchema)]
4443
pub struct Uint128(#[schemars(with = "String")] pub(crate) u128);
4544

45+
impl_int_serde!(Uint128);
4646
forward_ref_partial_eq!(Uint128, Uint128);
4747

4848
impl Uint128 {
@@ -583,46 +583,6 @@ impl<'a> ShlAssign<&'a u32> for Uint128 {
583583
}
584584
}
585585

586-
impl Serialize for Uint128 {
587-
/// Serializes as an integer string using base 10
588-
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
589-
where
590-
S: ser::Serializer,
591-
{
592-
serializer.serialize_str(&self.to_string())
593-
}
594-
}
595-
596-
impl<'de> Deserialize<'de> for Uint128 {
597-
/// Deserialized from an integer string using base 10
598-
fn deserialize<D>(deserializer: D) -> Result<Uint128, D::Error>
599-
where
600-
D: Deserializer<'de>,
601-
{
602-
deserializer.deserialize_str(Uint128Visitor)
603-
}
604-
}
605-
606-
struct Uint128Visitor;
607-
608-
impl<'de> de::Visitor<'de> for Uint128Visitor {
609-
type Value = Uint128;
610-
611-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
612-
formatter.write_str("string-encoded integer")
613-
}
614-
615-
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
616-
where
617-
E: de::Error,
618-
{
619-
match v.parse::<u128>() {
620-
Ok(u) => Ok(Uint128(u)),
621-
Err(e) => Err(E::custom(format_args!("invalid Uint128 '{v}' - {e}"))),
622-
}
623-
}
624-
}
625-
626586
impl<A> core::iter::Sum<A> for Uint128
627587
where
628588
Self: Add<A, Output = Self>,

0 commit comments

Comments
 (0)