I have the following json file that I want to deserialize in a Rust struct:
{
"name": "Manuel",
"friends": {
"id1": 1703692376,
...
}
...
}
The friends tag contains the ids and a timestamp
I created a Rust struct like this:
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct MyStruct{
name: String,
friends: HashMap<String, i64>
}
And that works fine, but I would actually like to have something like this:
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct MyStruct{
name: String,
friends: HashMap<String, SystemTime>
}
So I would like to transform the integer value to a SystemTime type. Is it possible to do that with serde?
2
Answers
First, lets create conversion functions
unix_seconds_to_system
andsystem_to_unix_seconds
to go betweeni64
andSystemTime
.Then, you can use
#[serde(with)]
to specify custom functions to use for deserialization and serialization instead of theDeserialize
andSerialize
implementations forHashMap<String, SystemTime>
.There are two ways to go about this. The simpler solution is to go through
HashMap<String, i64>
and converting.The downside is that this allocates two
HashMap
s when deserializing and one when serializing, instead of one and zero respectively. To avoid that, you can make fully custom functions usingSerializer
andDeserializer
methods directly.Playground
serde_with
has got you covered. It supports de/serialization ofSystemTime
from various formats, including seconds since epoch, and unlike#[serde(with)]
, it supports nested types: