mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-29 09:08:05 -05:00
chore: remove duplicate serde helpers (#5508)
This commit is contained in:
@@ -2,8 +2,9 @@ use crate::{
|
||||
constants::EMPTY_ROOT_HASH,
|
||||
keccak256,
|
||||
serde_helper::{
|
||||
deserialize_json_ttd_opt, deserialize_json_u256, deserialize_storage_map,
|
||||
json_u256::{deserialize_json_ttd_opt, deserialize_json_u256},
|
||||
num::{u64_hex_or_decimal, u64_hex_or_decimal_opt},
|
||||
storage::deserialize_storage_map,
|
||||
},
|
||||
trie::{HashBuilder, Nibbles},
|
||||
Account, Address, Bytes, B256, KECCAK_EMPTY, U256,
|
||||
|
||||
@@ -1,73 +1,6 @@
|
||||
//! [serde] utilities.
|
||||
|
||||
use crate::{B256, U64};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
mod storage;
|
||||
pub use storage::*;
|
||||
|
||||
pub use reth_rpc_types::json_u256::*;
|
||||
|
||||
pub mod num;
|
||||
pub use reth_rpc_types::serde_helpers::*;
|
||||
|
||||
mod prune;
|
||||
pub use prune::deserialize_opt_prune_mode_with_min_blocks;
|
||||
|
||||
/// serde functions for handling primitive `u64` as [`U64`].
|
||||
pub mod u64_hex {
|
||||
use super::*;
|
||||
|
||||
/// Deserializes an `u64` from [U64] accepting a hex quantity string with optional 0x prefix
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
U64::deserialize(deserializer).map(|val| val.to())
|
||||
}
|
||||
|
||||
/// Serializes u64 as hex string
|
||||
pub fn serialize<S: Serializer>(value: &u64, s: S) -> Result<S::Ok, S::Error> {
|
||||
U64::from(*value).serialize(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialize a byte vec as a hex string _without_ the "0x" prefix.
|
||||
///
|
||||
/// This behaves the same as [`hex::encode`](crate::hex::encode).
|
||||
pub fn serialize_hex_string_no_prefix<S, T>(x: T, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
T: AsRef<[u8]>,
|
||||
{
|
||||
s.serialize_str(&crate::hex::encode(x.as_ref()))
|
||||
}
|
||||
|
||||
/// Serialize a [B256] as a hex string _without_ the "0x" prefix.
|
||||
pub fn serialize_b256_hex_string_no_prefix<S>(x: &B256, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
s.serialize_str(&format!("{x:x}"))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[test]
|
||||
fn test_hex_u64() {
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
struct Value {
|
||||
#[serde(with = "u64_hex")]
|
||||
inner: u64,
|
||||
}
|
||||
|
||||
let val = Value { inner: 1000 };
|
||||
let s = serde_json::to_string(&val).unwrap();
|
||||
assert_eq!(s, "{\"inner\":\"0x3e8\"}");
|
||||
|
||||
let deserialized: Value = serde_json::from_str(&s).unwrap();
|
||||
assert_eq!(val, deserialized);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
//! Numeric helpers
|
||||
|
||||
use crate::{U256, U64};
|
||||
use serde::{de, Deserialize, Deserializer, Serialize};
|
||||
use std::str::FromStr;
|
||||
|
||||
/// A `u64` wrapper type that deserializes from hex or a u64 and serializes as hex.
|
||||
///
|
||||
///
|
||||
/// ```rust
|
||||
/// use reth_primitives::serde_helper::num::U64HexOrNumber;
|
||||
/// let number_json = "100";
|
||||
/// let hex_json = "\"0x64\"";
|
||||
///
|
||||
/// let number: U64HexOrNumber = serde_json::from_str(number_json).unwrap();
|
||||
/// let hex: U64HexOrNumber = serde_json::from_str(hex_json).unwrap();
|
||||
/// assert_eq!(number, hex);
|
||||
/// assert_eq!(hex.to(), 100);
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
|
||||
pub struct U64HexOrNumber(U64);
|
||||
|
||||
impl U64HexOrNumber {
|
||||
/// Returns the wrapped u64
|
||||
pub fn to(self) -> u64 {
|
||||
self.0.to()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for U64HexOrNumber {
|
||||
fn from(value: u64) -> Self {
|
||||
Self(U64::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<U64> for U64HexOrNumber {
|
||||
fn from(value: U64) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<U64HexOrNumber> for u64 {
|
||||
fn from(value: U64HexOrNumber) -> Self {
|
||||
value.to()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<U64HexOrNumber> for U64 {
|
||||
fn from(value: U64HexOrNumber) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for U64HexOrNumber {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum NumberOrHexU64 {
|
||||
Hex(U64),
|
||||
Int(u64),
|
||||
}
|
||||
match NumberOrHexU64::deserialize(deserializer)? {
|
||||
NumberOrHexU64::Int(val) => Ok(val.into()),
|
||||
NumberOrHexU64::Hex(val) => Ok(val.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// serde functions for handling primitive `u64` as [U64]
|
||||
pub mod u64_hex_or_decimal {
|
||||
use crate::serde_helper::num::U64HexOrNumber;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// Deserializes an `u64` accepting a hex quantity string with optional 0x prefix or
|
||||
/// a number
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
U64HexOrNumber::deserialize(deserializer).map(Into::into)
|
||||
}
|
||||
|
||||
/// Serializes u64 as hex string
|
||||
pub fn serialize<S: Serializer>(value: &u64, s: S) -> Result<S::Ok, S::Error> {
|
||||
U64HexOrNumber::from(*value).serialize(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// serde functions for handling primitive optional `u64` as [U64]
|
||||
pub mod u64_hex_or_decimal_opt {
|
||||
use crate::serde_helper::num::U64HexOrNumber;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// Deserializes an `u64` accepting a hex quantity string with optional 0x prefix or
|
||||
/// a number
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
match Option::<U64HexOrNumber>::deserialize(deserializer)? {
|
||||
Some(val) => Ok(Some(val.into())),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Serializes u64 as hex string
|
||||
pub fn serialize<S: Serializer>(value: &Option<u64>, s: S) -> Result<S::Ok, S::Error> {
|
||||
match value {
|
||||
Some(val) => U64HexOrNumber::from(*val).serialize(s),
|
||||
None => s.serialize_none(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserializes the input into an `Option<U256>`, using [`from_int_or_hex`] to deserialize the
|
||||
/// inner value.
|
||||
pub fn from_int_or_hex_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
match Option::<NumberOrHexU256>::deserialize(deserializer)? {
|
||||
Some(val) => val.try_into_u256().map(Some),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserializes the input into a U256, accepting both 0x-prefixed hex and decimal strings with
|
||||
/// arbitrary precision, defined by serde_json's [`Number`](serde_json::Number).
|
||||
pub fn from_int_or_hex<'de, D>(deserializer: D) -> Result<U256, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
NumberOrHexU256::deserialize(deserializer)?.try_into_u256()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(untagged)]
|
||||
enum NumberOrHexU256 {
|
||||
Int(serde_json::Number),
|
||||
Hex(U256),
|
||||
}
|
||||
|
||||
impl NumberOrHexU256 {
|
||||
fn try_into_u256<E: de::Error>(self) -> Result<U256, E> {
|
||||
match self {
|
||||
NumberOrHexU256::Int(num) => {
|
||||
U256::from_str(num.to_string().as_str()).map_err(E::custom)
|
||||
}
|
||||
NumberOrHexU256::Hex(val) => Ok(val),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_u256_int_or_hex() {
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
struct V(#[serde(deserialize_with = "from_int_or_hex")] U256);
|
||||
|
||||
proptest::proptest!(|(value: u64)| {
|
||||
let u256_val = U256::from(value);
|
||||
|
||||
let num_obj = serde_json::to_string(&value).unwrap();
|
||||
let hex_obj = serde_json::to_string(&u256_val).unwrap();
|
||||
|
||||
let int_val:V = serde_json::from_str(&num_obj).unwrap();
|
||||
let hex_val = serde_json::from_str(&hex_obj).unwrap();
|
||||
assert_eq!(int_val, hex_val);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_u256_int_or_hex_opt() {
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
struct V(#[serde(deserialize_with = "from_int_or_hex_opt")] Option<U256>);
|
||||
|
||||
let null = serde_json::to_string(&None::<U256>).unwrap();
|
||||
let val: V = serde_json::from_str(&null).unwrap();
|
||||
assert!(val.0.is_none());
|
||||
|
||||
proptest::proptest!(|(value: u64)| {
|
||||
let u256_val = U256::from(value);
|
||||
|
||||
let num_obj = serde_json::to_string(&value).unwrap();
|
||||
let hex_obj = serde_json::to_string(&u256_val).unwrap();
|
||||
|
||||
let int_val:V = serde_json::from_str(&num_obj).unwrap();
|
||||
let hex_val = serde_json::from_str(&hex_obj).unwrap();
|
||||
assert_eq!(int_val, hex_val);
|
||||
assert_eq!(int_val.0, Some(u256_val));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_hex_or_number_u64() {
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
struct V(U64HexOrNumber);
|
||||
|
||||
proptest::proptest!(|(value: u64)| {
|
||||
let val = U64::from(value);
|
||||
|
||||
let num_obj = serde_json::to_string(&value).unwrap();
|
||||
let hex_obj = serde_json::to_string(&val).unwrap();
|
||||
|
||||
let int_val:V = serde_json::from_str(&num_obj).unwrap();
|
||||
let hex_val = serde_json::from_str(&hex_obj).unwrap();
|
||||
assert_eq!(int_val, hex_val);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
use crate::{Bytes, B256, U256};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::{collections::HashMap, fmt::Write};
|
||||
|
||||
/// A storage key type that can be serialized to and from a hex string up to 32 bytes. Used for
|
||||
/// `eth_getStorageAt` and `eth_getProof` RPCs.
|
||||
///
|
||||
/// This is a wrapper type meant to mirror geth's serialization and deserialization behavior for
|
||||
/// storage keys.
|
||||
///
|
||||
/// In `eth_getStorageAt`, this is used for deserialization of the `index` field. Internally, the
|
||||
/// index is a [B256], but in `eth_getStorageAt` requests, its serialization can be _up to_ 32
|
||||
/// bytes. To support this, the storage key is deserialized first as a U256, and converted to a
|
||||
/// B256 for use internally.
|
||||
///
|
||||
/// `eth_getProof` also takes storage keys up to 32 bytes as input, so the `keys` field is
|
||||
/// similarly deserialized. However, geth populates the storage proof `key` fields in the response
|
||||
/// by mirroring the `key` field used in the input.
|
||||
/// * See how `storageKey`s (the input) are populated in the `StorageResult` (the output):
|
||||
/// <https://github.com/ethereum/go-ethereum/blob/00a73fbcce3250b87fc4160f3deddc44390848f4/internal/ethapi/api.go#L658-L690>
|
||||
///
|
||||
/// The contained [B256] and From implementation for String are used to preserve the input and
|
||||
/// implement this behavior from geth.
|
||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(from = "U256", into = "String")]
|
||||
pub struct JsonStorageKey(pub B256);
|
||||
|
||||
impl From<U256> for JsonStorageKey {
|
||||
fn from(value: U256) -> Self {
|
||||
// SAFETY: Address (B256) and U256 have the same number of bytes
|
||||
JsonStorageKey(B256::from(value.to_be_bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<JsonStorageKey> for String {
|
||||
fn from(value: JsonStorageKey) -> Self {
|
||||
// SAFETY: Address (B256) and U256 have the same number of bytes
|
||||
let uint = U256::from_be_bytes(value.0 .0);
|
||||
|
||||
// serialize byte by byte
|
||||
//
|
||||
// this is mainly so we can return an output that hive testing expects, because the
|
||||
// `eth_getProof` implementation in geth simply mirrors the input
|
||||
//
|
||||
// see the use of `hexKey` in the `eth_getProof` response:
|
||||
// <https://github.com/ethereum/go-ethereum/blob/00a73fbcce3250b87fc4160f3deddc44390848f4/internal/ethapi/api.go#L658-L690>
|
||||
let bytes = uint.to_be_bytes_trimmed_vec();
|
||||
let mut hex = String::with_capacity(2 + bytes.len() * 2);
|
||||
hex.push_str("0x");
|
||||
for byte in bytes {
|
||||
write!(hex, "{:02x}", byte).unwrap();
|
||||
}
|
||||
hex
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a Bytes value into a B256, accepting inputs that are less than 32 bytes long. These
|
||||
/// inputs will be left padded with zeros.
|
||||
pub fn from_bytes_to_b256<'de, D>(bytes: Bytes) -> Result<B256, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
if bytes.0.len() > 32 {
|
||||
return Err(serde::de::Error::custom("input too long to be a B256"))
|
||||
}
|
||||
|
||||
// left pad with zeros to 32 bytes
|
||||
let mut padded = [0u8; 32];
|
||||
padded[32 - bytes.0.len()..].copy_from_slice(&bytes.0);
|
||||
|
||||
// then convert to B256 without a panic
|
||||
Ok(B256::from_slice(&padded))
|
||||
}
|
||||
|
||||
/// Deserializes the input into an Option<HashMap<B256, B256>>, using [from_bytes_to_b256] which
|
||||
/// allows cropped values:
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "0x0000000000000000000000000000000000000000000000000000000000000001": "0x22"
|
||||
/// }
|
||||
/// ```
|
||||
pub fn deserialize_storage_map<'de, D>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<HashMap<B256, B256>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let map = Option::<HashMap<Bytes, Bytes>>::deserialize(deserializer)?;
|
||||
match map {
|
||||
Some(mut map) => {
|
||||
let mut res_map = HashMap::with_capacity(map.len());
|
||||
for (k, v) in map.drain() {
|
||||
let k_deserialized = from_bytes_to_b256::<'de, D>(k)?;
|
||||
let v_deserialized = from_bytes_to_b256::<'de, D>(v)?;
|
||||
res_map.insert(k_deserialized, v_deserialized);
|
||||
}
|
||||
Ok(Some(res_map))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
@@ -447,7 +447,7 @@ pub struct OptimismPayloadAttributes {
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
deserialize_with = "crate::serde_helpers::u64_hex::u64_hex_opt::deserialize"
|
||||
deserialize_with = "crate::serde_helpers::u64_hex_opt::deserialize"
|
||||
)]
|
||||
pub gas_limit: Option<u64>,
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ mod otterscan;
|
||||
mod peer;
|
||||
pub mod relay;
|
||||
mod rpc;
|
||||
mod serde_helpers;
|
||||
pub mod serde_helpers;
|
||||
|
||||
pub use admin::*;
|
||||
pub use eth::*;
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
//! Serde helpers for primitive types.
|
||||
|
||||
use alloy_primitives::U256;
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
use alloy_primitives::B256;
|
||||
use serde::Serializer;
|
||||
|
||||
pub mod json_u256;
|
||||
pub use json_u256::JsonU256;
|
||||
|
||||
/// Helpers for dealing with numbers.
|
||||
pub mod num;
|
||||
pub use num::*;
|
||||
|
||||
/// Storage related helpers.
|
||||
pub mod storage;
|
||||
pub mod u64_hex;
|
||||
|
||||
/// Deserializes the input into a U256, accepting both 0x-prefixed hex and decimal strings with
|
||||
/// arbitrary precision, defined by serde_json's [`Number`](serde_json::Number).
|
||||
pub fn from_int_or_hex<'de, D>(deserializer: D) -> Result<U256, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
num::NumberOrHexU256::deserialize(deserializer)?.try_into_u256()
|
||||
}
|
||||
pub use storage::JsonStorageKey;
|
||||
|
||||
/// Serialize a byte vec as a hex string _without_ the "0x" prefix.
|
||||
///
|
||||
@@ -28,3 +24,11 @@ where
|
||||
{
|
||||
s.serialize_str(&alloy_primitives::hex::encode(x.as_ref()))
|
||||
}
|
||||
|
||||
/// Serialize a [B256] as a hex string _without_ the "0x" prefix.
|
||||
pub fn serialize_b256_hex_string_no_prefix<S>(x: &B256, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
s.serialize_str(&format!("{x:x}"))
|
||||
}
|
||||
|
||||
@@ -69,6 +69,68 @@ impl<'de> Deserialize<'de> for U64HexOrNumber {
|
||||
}
|
||||
}
|
||||
|
||||
/// serde functions for handling `u64` as [U64]
|
||||
pub mod u64_hex {
|
||||
use alloy_primitives::U64;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// Deserializes an `u64` from [U64] accepting a hex quantity string with optional 0x prefix
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
U64::deserialize(deserializer).map(|val| val.to())
|
||||
}
|
||||
|
||||
/// Serializes u64 as hex string
|
||||
pub fn serialize<S: Serializer>(value: &u64, s: S) -> Result<S::Ok, S::Error> {
|
||||
U64::from(*value).serialize(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// serde functions for handling `Option<u64>` as [U64]
|
||||
pub mod u64_hex_opt {
|
||||
use alloy_primitives::U64;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// Serializes u64 as hex string
|
||||
pub fn serialize<S: Serializer>(value: &Option<u64>, s: S) -> Result<S::Ok, S::Error> {
|
||||
match value {
|
||||
Some(val) => U64::from(*val).serialize(s),
|
||||
None => s.serialize_none(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Deserializes an `Option` from [U64] accepting a hex quantity string with optional 0x prefix
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(U64::deserialize(deserializer)
|
||||
.map_or(None, |v| Some(u64::from_be_bytes(v.to_be_bytes()))))
|
||||
}
|
||||
}
|
||||
|
||||
/// serde functions for handling primitive `u64` as [U64]
|
||||
pub mod u64_hex_or_decimal {
|
||||
use crate::serde_helpers::num::U64HexOrNumber;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// Deserializes an `u64` accepting a hex quantity string with optional 0x prefix or
|
||||
/// a number
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
U64HexOrNumber::deserialize(deserializer).map(Into::into)
|
||||
}
|
||||
|
||||
/// Serializes u64 as hex string
|
||||
pub fn serialize<S: Serializer>(value: &u64, s: S) -> Result<S::Ok, S::Error> {
|
||||
U64HexOrNumber::from(*value).serialize(s)
|
||||
}
|
||||
}
|
||||
|
||||
/// serde functions for handling primitive optional `u64` as [U64]
|
||||
pub mod u64_hex_or_decimal_opt {
|
||||
use crate::serde_helpers::num::U64HexOrNumber;
|
||||
@@ -137,3 +199,25 @@ where
|
||||
{
|
||||
NumberOrHexU256::deserialize(deserializer)?.try_into_u256()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[test]
|
||||
fn test_hex_u64() {
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
struct Value {
|
||||
#[serde(with = "u64_hex")]
|
||||
inner: u64,
|
||||
}
|
||||
|
||||
let val = Value { inner: 1000 };
|
||||
let s = serde_json::to_string(&val).unwrap();
|
||||
assert_eq!(s, "{\"inner\":\"0x3e8\"}");
|
||||
|
||||
let deserialized: Value = serde_json::from_str(&s).unwrap();
|
||||
assert_eq!(val, deserialized);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
//! Helper to deserialize an `u64` from [U64] accepting a hex quantity string with optional 0x
|
||||
//! prefix
|
||||
|
||||
use alloy_primitives::U64;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
/// Deserializes an `u64` from [U64] accepting a hex quantity string with optional 0x prefix
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<u64, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
U64::deserialize(deserializer).map(|val| val.to())
|
||||
}
|
||||
|
||||
/// Serializes u64 as hex string
|
||||
pub fn serialize<S: Serializer>(value: &u64, s: S) -> Result<S::Ok, S::Error> {
|
||||
U64::from(*value).serialize(s)
|
||||
}
|
||||
|
||||
/// serde functions for handling `Option<u64>` as [U64]
|
||||
pub mod u64_hex_opt {
|
||||
use alloy_primitives::U64;
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
/// Deserializes an `Option` from [U64] accepting a hex quantity string with optional 0x prefix
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<u64>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(U64::deserialize(deserializer)
|
||||
.map_or(None, |v| Some(u64::from_be_bytes(v.to_be_bytes()))))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user