Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialize JSON list of hex strings as bytes

Tags:

rust

serde

Iʼm trying to read a JSON stream, part of which looks like

  "data": [
    "c1a8f800a4393e0cacd05a5bc60ae3e0",
    "bbac4013c1ca3482155b584d35dac185",
    "685f237d4fcbd191c981b94ef6986cde",
    "a08898e81f1ddb6612aa12641b856aa9"
  ]

(there are more entries in the data list and each each entry is longer, but this should be illustrative; both the length of the list and the length of each hex string is known at compile time)

Ideally Iʼd want a single [u8; 64] (the actual size is known at compile time), or failing that, a Vec<u8>, but I imagine itʼs easier to deseriazie it as a Vec<[u8; 16]> and merge them later. However, Iʼm having trouble doing even that.

The hex crate has a way to deserialize a single hex string as a Vec or array of u8, but I canʼt figure out how to tell Serde to do that for each entry of the list. Is there a simple way to do that Iʼm overlooking, or do I need to write my own list deserializer?

like image 904
Daniel H Avatar asked Dec 18 '22 10:12

Daniel H


1 Answers

Serde has the power to use serializers and deserializers from other crates in a nested fashion using #[serde(with = "...")]. Since hex has a serde feature, this can be easily done.

Here is a simple example using serde_json and hex.

cargo.toml

serde = { version =  "1.0.133",  features = ["derive"] }
serde_json = "1.0.74"
hex = { version = "0.4", features = ["serde"] }

main.rs

use serde::{Deserialize, Serialize};
use serde_json::Result;

#[derive(Serialize, Deserialize, Debug)]
struct MyData {
    data: Vec<MyHex>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(transparent)]
struct MyHex {
    #[serde(with = "hex::serde")]
    hex: Vec<u8>,
}


fn main() -> Result<()> {
    let data = r#"
    {
        "data": [
            "c1a8f800a4393e0cacd05a5bc60ae3e0",
            "bbac4013c1ca3482155b584d35dac185",
            "685f237d4fcbd191c981b94ef6986cde",
            "a08898e81f1ddb6612aa12641b856aa9"
        ]
    }
    "#';

    let my_data: MyData = serde_json::from_str(data)?;

    println!("{:?}", my_data); // MyData { data: [MyHex { hex: [193, 168, 248, 0, 164, 57, 62, 12, 172, 208, 90, 91, 198, 10, 227, 224] }, MyHex { hex: [187, 172, 64, 19, 193, 202, 52, 130, 21, 91, 88, 77, 53, 218, 193, 133] }, MyHex { hex: [104, 95, 35, 125, 79, 203, 209, 145, 201, 129, 185, 78, 246, 152, 108, 222] }, MyHex { hex: [160, 136, 152, 232, 31, 29, 219, 102, 18, 170, 18, 100, 27, 133, 106, 169] }] }


    return Ok(());
}

Serde With Reference
Hex Serde Reference

like image 114
Adam Comer Avatar answered Jan 11 '23 21:01

Adam Comer