essential_types/serde/
hash.rs

1//! Custom hash serialization to better support human-readable formats.
2
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5/// Serialize a fixed-size hash value (`ContentAddress`, `Signature`).
6pub fn serialize<const N: usize, S>(bytes: &[u8; N], s: S) -> Result<S::Ok, S::Error>
7where
8    S: Serializer,
9{
10    if s.is_human_readable() {
11        let string = hex::encode_upper(bytes);
12        string.serialize(s)
13    } else {
14        bytes[..].serialize(s)
15    }
16}
17
18/// Deserialize a fixed-size hash value (`ContentAddress`, `Signature`).
19pub fn deserialize<'de, const N: usize, D>(d: D) -> Result<[u8; N], D::Error>
20where
21    D: Deserializer<'de>,
22    [u8; N]: TryFrom<Vec<u8>>,
23{
24    let bytes: Vec<u8> = if d.is_human_readable() {
25        let string = String::deserialize(d)?;
26        hex::decode(string).map_err(serde::de::Error::custom)?
27    } else {
28        Vec::deserialize(d)?
29    };
30    let len = bytes.len();
31    bytes.try_into().map_err(|_err| {
32        let msg = format!("failed to convert `Vec<u8>` with length {len} to `[u8; {N}]`");
33        serde::de::Error::custom(msg)
34    })
35}