Skip to content

Commit

Permalink
feat: add serde feature
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Oct 25, 2024
1 parent 4c37ccd commit 064207e
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ std = []
# "signature" crate.)
traits-preview = ["digest"]

# Adds serialization and deserialization abilities to `Hash`
serde = ["dep:serde"]

# ---------- Features below this line are undocumented and unstable. ----------
# The following features are mainly intended for testing and benchmarking, and
# they might change or disappear at any time without a major version bump.
Expand Down Expand Up @@ -91,6 +94,7 @@ rayon = { version = "1.2.1", optional = true }
cfg-if = "1.0.0"
digest = { version = "0.10.1", features = [ "mac" ], optional = true }
zeroize_crate = { package = "zeroize", version = "1", default-features = false, features = ["zeroize_derive"], optional = true }
serde = { version = "1.0.213", optional = true }

[dev-dependencies]
hex = "0.4.2"
Expand All @@ -99,6 +103,8 @@ rand = "0.8.0"
rand_chacha = "0.3.0"
reference_impl = { path = "./reference_impl" }
hmac = "0.12.0"
postcard = { version = "1.0.10", features = ["use-std"] }
serde_json = "1.0.132"

[build-dependencies]
cc = "1.0.4"
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ extern crate zeroize_crate as zeroize; // Needed because `zeroize::Zeroize` assu
#[cfg(test)]
mod test;

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

// The guts module is for incremental use cases like the `bao` crate that need
// to explicitly compute chunk and parent chaining values. It is semi-stable
// and likely to keep working, but largely undocumented and not intended for
Expand Down
58 changes: 58 additions & 0 deletions src/serde.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

use super::Hash;

impl Serialize for Hash {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if serializer.is_human_readable() {
serializer.serialize_str(self.to_string().as_str())
} else {
self.as_bytes().serialize(serializer)
}
}
}

impl<'de> Deserialize<'de> for Hash {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = String::deserialize(deserializer)?;
s.parse().map_err(de::Error::custom)
} else {
let data: [u8; 32] = Deserialize::deserialize(deserializer)?;
Ok(Hash::from(data))
}
}
}

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

use crate::hash;

#[test]
fn test_hash_postcard() {
let hash = hash(b"hello");
let ser = postcard::to_stdvec(&hash).unwrap();
let de: Hash = postcard::from_bytes(&ser).unwrap();
assert_eq!(hash, de);

assert_eq!(ser.len(), 32);
}

#[test]
fn test_hash_json() {
let hash = hash(b"hello");
let ser = serde_json::to_string(&hash).unwrap();
let de: Hash = serde_json::from_str(&ser).unwrap();
assert_eq!(hash, de);
// 64 bytes of hex + 2 quotes
assert_eq!(ser.len(), 66);
}
}

0 comments on commit 064207e

Please sign in to comment.