Search code examples
jsonserializationrustserde

How do I serialize and deserialize a tuple in Rust using Serde?


I have a tuple consisting of an String and a Uuid that I serialize using serde_json:

let log_and_id = (String::from("Test string"), test_id);
let log_and_id_serialized = serde_json::to_string(&log_and_id)
        .expect("Serialization failed");
//After serialization (debug print): "[\"Test string\",\"32a8e12d-69d2-421d-a52e-1ee76cc03ed5\"]"

Then I transfer this serialized value over the network and receive a BytesMut (serialized_tuple) on the other end, which I try to deserialize:

//Bytesmut value (debug print): b"\"[\\\"Test string\\\",\\\"32a8e12d-69d2-421d-a52e-1ee76cc03ed5\\\"]\""
let (log, operation_state_id) = serde_json::from_slice::<(String, Uuid)>(&serialized_tuple)?;

But I get the following error:

ERROR actix_http::response] Internal Server Error: SerdeError(Error("invalid type: string \"[\\\"Test string\\\",\\\"32a8e12d-69d2-421d-a52e-1ee76cc03ed5\\\"]\", expected a tuple of size 2", line: 1, column: 68))

(De)serializing single objects this way used to work in other parts of this code, so what could cause it to fail when used with tuples?


Solution

  • You don't have a serialized tuple, but a serialized serialized tuple.

    I mean the serialization of the tuple, which was a JSON string, was again serialized.

    You can check this with this code (playground):

    let serialized_tuple =  b"\"[\\\"Test string\\\",\\\"32a8e12d-69d2-421d-a52e-1ee76cc03ed5\\\"]\"";
    let serialized_tuple: String =  serde_json::from_slice(serialized_tuple).unwrap();
    let (log, operation_state_id) = serde_json::from_slice::<(String, String)>(serialized_tuple.as_bytes()).unwrap();
    

    which produces the desired tuple.

    Of course, rather than deserializing twice, you should remove the unnecessary serialization from your application (it's not in the code you've shown).