I stumbled across a crate which implemented string parsing that I
wished to incorporate into some of my serde.rs
deserialization code. Unfortunately the crate in question,
cron does not implement the
#[derive(Deserialize)]
macro on its Schedule
, so I needed to fiddle with
one of serde’s “field attributes” in order to move forward: deserialize_with
.
Below is an example of my code, which was inspired by this comment I stumbled across on GitHub:
use serde::de::{Deserialize, Deserializer};
use std::str::FromStr;
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Trigger {
#[serde(deserialize_with = "deserialize_cron_schedule")]
cron: cron::Schedule,
}
fn deserialize_cron_schedule<'de, D>(deserializer: D) -> Result<cron::Schedule, D::Error>
where D: Deserializer<'de> {
let buf = String::deserialize(deserializer)?;
cron::Schedule::from_str(&buf).map_err(serde::de::Error::custom)
}
I won’t bother to explain what’s going on here, because I don’t understand much
of it anyways. But the gist is that String::deserialize
gets us a String
to
work with, which can then be passed along to the “real” parsing code.
I hope this code snippet helps, I know it will sure make deserializing certain types of strings in my serde types much easier!