I am trying to implement a custom JSON deserialize function using serde.
The data type I am working with looks like this -
pub enum MarionetteResponse {
#[serde(deserialize_with = "deserialize_data", serialize_with = "serialize_data")]
String(String),
}
The JSON value I receive resembles {"value": "foo"} and I wanted to convert it to the following -
MarionetteResponse::String("foo".into())
I have been trying to implement a generic Visitor for this purpose as there will be many more such types-
fn deserialize_data<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
D: Deserializer<'de>,
T: serde:: de::DeserializeOwned,
{
#[derive(Deserialize)]
struct Wrapper<T> {
value: T,
}
struct WrapperVisitor;
impl<'de, T> Visitor<'de> for WrapperVisitor
where
T: serde::de::DeserializeOwned,
{
type Value = Wrapper<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("temporary struct Wrapper")
}
fn visit_map<V>(self, mut map: V) -> Result<Wrapper<T>, V::Error>
where
V: MapAccess<'de>,
{
let mut val = None;
while let Some(key) = map.next_key()? {
match key {
"value" => {
if val.is_some() {
return Err(de::Error::duplicate_field("value"));
}
val = Some(map.next_value()?);
}
}
}
let value = val.ok_or_else(|| de::Error::missing_field("value"))?;
Ok(Wrapper {value})
}
}
const FIELD: &'static [&'static str]= &["value"];
let w = deserializer.deserialize_struct("Wrapper", FIELD, WrapperVisitor).map_err(de::Error::custom)?;
Ok(w.value)
I am not sure if this is the optimal approach. But, my immediate problem is the error:
| impl<'de, T> Visitor<'de> for WrapperVisitor
| ^ unconstrained type parameter
Any suggestions to improve upon this approach and remove this error are welcome.
Please find the link to repository if you wish to understand the bigger picture (branch = bmodel) -
https://github.com/andreastt/marionette-rs/commit/e963fc61328e58639624490b753abc3adb2e54ec
Thanks a lot......!