From d536af31411289103b394491064426e740407c70 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 25 Aug 2022 10:50:41 +0200 Subject: [PATCH 1/6] Add conversion and default functions for `NumberOrHex` --- subxt/src/rpc.rs | 102 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs index 1be869e122..773086bc7c 100644 --- a/subxt/src/rpc.rs +++ b/subxt/src/rpc.rs @@ -135,6 +135,85 @@ impl From for BlockNumber { } } +impl Default for NumberOrHex { + fn default() -> Self { + Self::Number(Default::default()) + } +} + +impl NumberOrHex { + /// Converts this number into an U256. + pub fn into_u256(self) -> U256 { + match self { + NumberOrHex::Number(n) => n.into(), + NumberOrHex::Hex(h) => h, + } + } +} + +impl From for NumberOrHex { + fn from(n: u32) -> Self { + NumberOrHex::Number(n.into()) + } +} + +impl From for NumberOrHex { + fn from(n: u64) -> Self { + NumberOrHex::Number(n) + } +} + +impl From for NumberOrHex { + fn from(n: u128) -> Self { + NumberOrHex::Hex(n.into()) + } +} + +impl From for NumberOrHex { + fn from(n: U256) -> Self { + NumberOrHex::Hex(n) + } +} + +/// An error type that signals an out-of-range conversion attempt. +pub struct TryFromIntError(pub(crate) ()); + +impl TryFrom for u32 { + type Error = TryFromIntError; + fn try_from(num_or_hex: NumberOrHex) -> Result { + num_or_hex + .into_u256() + .try_into() + .map_err(|_| TryFromIntError(())) + } +} + +impl TryFrom for u64 { + type Error = TryFromIntError; + fn try_from(num_or_hex: NumberOrHex) -> Result { + num_or_hex + .into_u256() + .try_into() + .map_err(|_| TryFromIntError(())) + } +} + +impl TryFrom for u128 { + type Error = TryFromIntError; + fn try_from(num_or_hex: NumberOrHex) -> Result { + num_or_hex + .into_u256() + .try_into() + .map_err(|_| TryFromIntError(())) + } +} + +impl From for U256 { + fn from(num_or_hex: NumberOrHex) -> U256 { + num_or_hex.into_u256() + } +} + // All unsigned ints can be converted into a BlockNumber: macro_rules! into_block_number { ($($t: ty)+) => { @@ -639,6 +718,19 @@ fn to_hex(bytes: impl AsRef<[u8]>) -> String { mod test { use super::*; + /// A util function to assert the result of serialization and deserialization is the same. + #[cfg(test)] + pub(crate) fn assert_deser(s: &str, expected: T) + where + T: std::fmt::Debug + + serde::ser::Serialize + + serde::de::DeserializeOwned + + PartialEq, + { + assert_eq!(serde_json::from_str::(s).unwrap(), expected); + assert_eq!(serde_json::to_string(&expected).unwrap(), s); + } + #[test] fn test_deser_runtime_version() { let val: RuntimeVersion = serde_json::from_str( @@ -664,4 +756,14 @@ mod test { } ); } + + #[test] + fn should_serialize_and_deserialize() { + assert_deser(r#""0x1234""#, NumberOrHex::Hex(0x1234.into())); + assert_deser(r#""0x0""#, NumberOrHex::Hex(0.into())); + assert_deser(r#"5"#, NumberOrHex::Number(5)); + assert_deser(r#"10000"#, NumberOrHex::Number(10000)); + assert_deser(r#"0"#, NumberOrHex::Number(0)); + assert_deser(r#"1000000000000"#, NumberOrHex::Number(1000000000000)); + } } From ba4966666861dfee1478f1c5bbf5abd698395881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 25 Aug 2022 11:06:27 +0200 Subject: [PATCH 2/6] Update subxt/src/rpc.rs Co-authored-by: Andrew Jones --- subxt/src/rpc.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs index 773086bc7c..f3b131e0c3 100644 --- a/subxt/src/rpc.rs +++ b/subxt/src/rpc.rs @@ -176,6 +176,7 @@ impl From for NumberOrHex { } /// An error type that signals an out-of-range conversion attempt. +#[derive(thiserror::Error)] pub struct TryFromIntError(pub(crate) ()); impl TryFrom for u32 { From c276e7c7f0ef6288478a52f9700de3d55845e13d Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 25 Aug 2022 11:45:53 +0200 Subject: [PATCH 3/6] Derive `Debug` with `thiserror::Error` --- subxt/src/rpc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs index f3b131e0c3..5ebb4cd609 100644 --- a/subxt/src/rpc.rs +++ b/subxt/src/rpc.rs @@ -176,7 +176,7 @@ impl From for NumberOrHex { } /// An error type that signals an out-of-range conversion attempt. -#[derive(thiserror::Error)] +#[derive(Debug, thiserror::Error)] pub struct TryFromIntError(pub(crate) ()); impl TryFrom for u32 { From 9a5e3abf80bd0edd9f3694c00263207733877546 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 25 Aug 2022 11:46:17 +0200 Subject: [PATCH 4/6] Remove unnecessary `#[cfg(test)]` --- subxt/src/rpc.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs index 5ebb4cd609..af4a262bd6 100644 --- a/subxt/src/rpc.rs +++ b/subxt/src/rpc.rs @@ -720,7 +720,6 @@ mod test { use super::*; /// A util function to assert the result of serialization and deserialization is the same. - #[cfg(test)] pub(crate) fn assert_deser(s: &str, expected: T) where T: std::fmt::Debug From 498d9929d3e3cf3504fb5b6f1cb7c145bf333582 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 25 Aug 2022 12:39:47 +0200 Subject: [PATCH 5/6] =?UTF-8?q?Add=20`#[error(=E2=80=A6)]`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- subxt/src/rpc.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs index af4a262bd6..3cc389094d 100644 --- a/subxt/src/rpc.rs +++ b/subxt/src/rpc.rs @@ -177,7 +177,8 @@ impl From for NumberOrHex { /// An error type that signals an out-of-range conversion attempt. #[derive(Debug, thiserror::Error)] -pub struct TryFromIntError(pub(crate) ()); +#[error("Out-of-range conversion attempt")] +pub struct TryFromIntError(); impl TryFrom for u32 { type Error = TryFromIntError; @@ -185,7 +186,7 @@ impl TryFrom for u32 { num_or_hex .into_u256() .try_into() - .map_err(|_| TryFromIntError(())) + .map_err(|_| TryFromIntError()) } } @@ -195,7 +196,7 @@ impl TryFrom for u64 { num_or_hex .into_u256() .try_into() - .map_err(|_| TryFromIntError(())) + .map_err(|_| TryFromIntError()) } } @@ -205,7 +206,7 @@ impl TryFrom for u128 { num_or_hex .into_u256() .try_into() - .map_err(|_| TryFromIntError(())) + .map_err(|_| TryFromIntError()) } } From a4c7ef9a3d6a1a236cb55012976269f3725caa30 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Thu, 25 Aug 2022 12:53:02 +0200 Subject: [PATCH 6/6] Remove `()` --- subxt/src/rpc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subxt/src/rpc.rs b/subxt/src/rpc.rs index 3cc389094d..49a4979413 100644 --- a/subxt/src/rpc.rs +++ b/subxt/src/rpc.rs @@ -178,7 +178,7 @@ impl From for NumberOrHex { /// An error type that signals an out-of-range conversion attempt. #[derive(Debug, thiserror::Error)] #[error("Out-of-range conversion attempt")] -pub struct TryFromIntError(); +pub struct TryFromIntError; impl TryFrom for u32 { type Error = TryFromIntError; @@ -186,7 +186,7 @@ impl TryFrom for u32 { num_or_hex .into_u256() .try_into() - .map_err(|_| TryFromIntError()) + .map_err(|_| TryFromIntError) } } @@ -196,7 +196,7 @@ impl TryFrom for u64 { num_or_hex .into_u256() .try_into() - .map_err(|_| TryFromIntError()) + .map_err(|_| TryFromIntError) } } @@ -206,7 +206,7 @@ impl TryFrom for u128 { num_or_hex .into_u256() .try_into() - .map_err(|_| TryFromIntError()) + .map_err(|_| TryFromIntError) } }