Serde deserialize String into u64

I can’t find how to deserialize a JSON string into an integer type using serde.
My attempt won’t compile:

#[derive(Debug, Deserialize)]
struct WebsocketMessage {
    #[serde(deserialize_with = "str::parse")]
    timestamp: u64
}

>Solution :

Well, str::parse simply doesn’t have the right type. The type must be

fn<'de, D>(D) -> Result<T, D::Error> where D: Deserializer<'de>

as documented here.

So this function would work:

fn parse<'de, T, D>(de: D) -> Result<T, D::Error>
where
    D: serde::Deserializer<'de>,
    T: std::str::FromStr,
    <T as std::str::FromStr>::Err: std::fmt::Display,
{
    Ok(String::deserialize(de)?
        .parse()
        .map_err(serde::de::Error::custom)?)
}

Playground

But really, you’ll have an easier time by using the serde_with crate:

use serde_with::{DisplayFromStr, serde_as};

#[serde_as]
#[derive(Debug, Deserialize)]
struct WebsocketMessage {
    #[serde_as(as = "DisplayFromStr")]
    timestamp: u64,
}

serde_with also has some nice options for parsing timestamps, so you don’t even have to use u64.

Leave a Reply