Skip to content

Commit

Permalink
Fix serde impls for Address + add some tests (#159)
Browse files Browse the repository at this point in the history
serde::Serialize and serde::Deserialize were not symmetric. Also, add some roundtrip tests to guard against regressions.
  • Loading branch information
kim authored Aug 9, 2023
1 parent dec2955 commit 72893f8
Showing 1 changed file with 58 additions and 1 deletion.
59 changes: 58 additions & 1 deletion crates/lib/src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use crate::sats;
/// TODO: Evaluate replacing this with a literal Ipv6Address which is assigned
/// permanently to a database.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
pub struct Address(u128);

impl Address {
Expand Down Expand Up @@ -62,6 +61,16 @@ impl Address {
impl_serialize!([] Address, (self, ser) =>self.0.to_be_bytes().serialize(ser));
impl_deserialize!([] Address, de => <[u8; 16]>::deserialize(de).map(|v| Self(u128::from_be_bytes(v))));

#[cfg(feature = "serde")]
impl serde::Serialize for Address {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.to_hex().serialize(serializer)
}
}

#[cfg(feature = "serde")]
impl<'de> serde::Deserialize<'de> for Address {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
Expand All @@ -74,3 +83,51 @@ impl<'de> serde::Deserialize<'de> for Address {
}

impl_st!([] Address, _ts => sats::AlgebraicType::U128);

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_bsatn_roundtrip() {
let addr = Address(rand::random());
let ser = sats::bsatn::to_vec(&addr).unwrap();
let de = sats::bsatn::from_slice(&ser).unwrap();
assert_eq!(addr, de);
}

#[cfg(feature = "serde")]
mod serde {
use super::*;

#[test]
fn test_serde_roundtrip() {
let addr = Address(rand::random());
let ser = serde_json::to_vec(&addr).unwrap();
let de = serde_json::from_slice(&ser).unwrap();
assert_eq!(addr, de);
}
}

// At some point, using `Address` in a spacetimedb table was not working
// (buffer length errors were thrown when deserializing). This test exists
// to guard against a regression.
#[test]
fn test_addr_column_rountrip() {
use spacetimedb_bindings_macro::{Deserialize, Serialize};

#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
struct MyTable {
name: String,
addr: Address,
}

let val = MyTable {
name: "example.com".into(),
addr: Address(rand::random()),
};
let ser = sats::bsatn::to_vec(&val).unwrap();
let de = sats::bsatn::from_slice(&ser).unwrap();
assert_eq!(val, de);
}
}

0 comments on commit 72893f8

Please sign in to comment.