Skip to content

Commit

Permalink
address: rework serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
bmwill committed Feb 22, 2024
1 parent 4259230 commit aabbafd
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 90 deletions.
14 changes: 11 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@ edition = "2021"

[package.metadata.docs.rs]
# To build locally:
# RUSTDOCFLAGS="--cfg doc_cfg" RUSTC_BOOTSTRAP=1 cargo doc --all-features --no-deps --open
# RUSTDOCFLAGS="--cfg=doc_cfg -Zunstable-options --generate-link-to-definition" RUSTC_BOOTSTRAP=1 cargo doc --all-features --no-deps --open
all-features = true
rustdoc-args = ["--cfg", "doc_cfg"]
rustdoc-args = [
# Enable doc_cfg showing the required features.
"--cfg=doc_cfg",

# Generate links to definition in rustdoc source code pages
# https://github.com/rust-lang/rust/pull/84176
"-Zunstable-options", "--generate-link-to-definition"
]

[features]
default = []
Expand All @@ -20,13 +27,14 @@ hex = "0.4.3"
# Serialization and Deserialization support
serde = { version = "1.0.197", optional = true }
serde_derive = { version = "1.0.197", optional = true }
serde_with = { version = "3.6.1", optional = true }
serde_with = { version = "3.6.1", default-features = false, optional = true }

# RNG support
rand_core = { version = "0.6.4", optional = true }

[dev-dependencies]
serde_json = "*"
bcs = "*"

[target.wasm32-unknown-unknown.dev-dependencies]
wasm-bindgen-test = "0.3"
Expand Down
4 changes: 0 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

pub mod types;


#[cfg(feature = "serde")]
mod serde_readable;

pub fn add(left: usize, right: usize) -> usize {
left + right
}
Expand Down
56 changes: 0 additions & 56 deletions src/serde_readable.rs

This file was deleted.

61 changes: 34 additions & 27 deletions src/types/address.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
#[derive(Clone, Copy, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub struct Address([u8; Self::LENGTH]);
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct Address(
#[cfg_attr(
feature = "serde",
serde(with = "::serde_with::As::<::serde_with::IfIsHumanReadable<ReadableAddress>>")
)]
[u8; Self::LENGTH],
);

impl Address {
pub const LENGTH: usize = 32;
Expand All @@ -21,7 +31,7 @@ impl Address {
}

/// Return the underlying byte array of a Address.
pub fn to_inner(self) -> [u8; Self::LENGTH] {
pub fn into_inner(self) -> [u8; Self::LENGTH] {
self.0
}

Expand Down Expand Up @@ -104,42 +114,29 @@ impl std::fmt::Debug for Address {

#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
impl serde::Serialize for Address {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
struct ReadableAddress;

#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
impl serde_with::SerializeAs<[u8; Address::LENGTH]> for ReadableAddress {
fn serialize_as<S>(source: &[u8; Address::LENGTH], serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if serializer.is_human_readable() {
self.to_hex().serialize(serializer)
} else {
serializer.serialize_newtype_struct("Address", &self.0)
}
let address = Address::new(*source);
serde_with::DisplayFromStr::serialize_as(&address, serializer)
}
}

#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
impl<'de> serde::Deserialize<'de> for Address {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
impl<'de> serde_with::DeserializeAs<'de, [u8; Address::LENGTH]> for ReadableAddress {
fn deserialize_as<D>(deserializer: D) -> Result<[u8; Address::LENGTH], D::Error>
where
D: serde::Deserializer<'de>,
{
use std::str::FromStr;

if deserializer.is_human_readable() {
let s = <String>::deserialize(deserializer)?;
Address::from_str(&s).map_err(serde::de::Error::custom)
} else {
// In order to preserve the Serde data model and help analysis tools,
// make sure to wrap our value in a container with the same name
// as the original type.
#[derive(::serde_derive::Deserialize)]
#[serde(rename = "Address")]
struct Value([u8; Address::LENGTH]);

let value = Value::deserialize(deserializer)?;
Ok(Address::new(value.0))
}
let address: Address = serde_with::DisplayFromStr::deserialize_as(deserializer)?;
Ok(address.into_inner())
}
}

Expand Down Expand Up @@ -169,4 +166,14 @@ mod test {

assert_eq!(actual.to_string(), expected);
}

#[test]
fn formats() {
let actual = Address::from_hex("0x2").unwrap();

println!("{}", serde_json::to_string(&actual).unwrap());
println!("{:?}", bcs::to_bytes(&actual).unwrap());
let a: Address = serde_json::from_str("\"0x2\"").unwrap();
println!("{a}");
}
}

0 comments on commit aabbafd

Please sign in to comment.