Custom JSON de/serialization question

So, I have a structure that looks like this and I am trying to change just a few details of how to serialize/deserialize without having to rewrite the whole process. I think all I need to do is implement the de/serialize for HashDigest and let the magic happen - although even this evades me

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Decode, Encode, PartialOrd)]
pub struct HashDigest {
    pub multihash: Multihash,
}

#[derive(Debug, Clone, Hash, PartialEq, Eq, Copy, Decode, Encode)]
pub struct Header {
    pub parent_hash: HashDigest,
    pub transactions_hash: HashDigest,
    pub committer: Address,
    pub timestamp: u64,
    pub ordinal: Ordinal,
    nonce: u128,
    hash: HashDigest,
}

pub type BlockSignature = Signature;
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, Decode, Encode, Hash)]
pub struct Block {
    pub header: Header,
    pub transactions: Vec<Transaction>,
    signature: BlockSignature,
}

pub type TransactionSignature = Signature;

#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq, Decode, Encode)]
pub struct Transaction {
    type_id: TransactionType,
    submitter: Address,
    timestamp: u64,
    payload: Vec<u8>,
    nonce: u128, // Adds a salt to harden
    hash: HashDigest,
    signature: TransactionSignature,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Decode)]
pub struct Signature {
    #[codec(encoded_as = "[u8; ed25519_dalek::Signature::BYTE_SIZE]")]
    pub signature: ed25519_dalek::Signature,
}

Which, when I use the default serialization produces (snipet)

  "header": {
    "parent_hash": {
      "multihash": {
        "code": 27,
        "size": 32,
        "digest": [
          197,
          210,
          70
        ]
      }
    },

Basically, anywhere there is a HashDigest I get

{
"multihash": {
        "code": 27,
        "size": 32,
        "digest": [
          197,
          210,
          70
        ]
      }
}

but what I'd really want is that anything that that is a HashDigest serializes as a long hex string instead of an array of base 10 numbers, like the below (which is how I would expect it to naturally express):

{
   "parent_hash" : "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}

BTW: This group is great! Thank you all for the help

You can just serialize_str() and pass the string representation of HashDigest:

impl Serialize for HashDigest {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        let hex_string = …; // it's not obvious what the conversion is
        serializer.serialize_str(&hex_string)
    }
}

I don't know how the Multihash is converted to a hex string, so I can't provide concrete code for that part of the problem.

2 Likes

Yeah, I think this will do. I will give it a try and report back. Obviously I will need to reverse this process too :slight_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.