Skip to content

Instantly share code, notes, and snippets.

@Mathspy
Created April 4, 2020 18:09
Show Gist options
  • Save Mathspy/1590273b322edd8b7f2a6e78be8d231a to your computer and use it in GitHub Desktop.
Save Mathspy/1590273b322edd8b7f2a6e78be8d231a to your computer and use it in GitHub Desktop.
Example of how to derive a custom `serde` Deserialize
use serde::{Deserialize, de::{self, Deserializer, Visitor}};
use std::fmt;
#[derive(Debug)]
enum Shape {
Triangle = 3,
Rectangle = 4,
Pentagon = 5,
}
impl<'de> Deserialize<'de> for Shape {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct EnumVisitor;
const VARIANTS: &'static [&'static str] = &["t", "r", "p"];
impl<'de> Visitor<'de> for EnumVisitor {
type Value = Shape;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`t` or `r` or `p`")
}
fn visit_str<E>(self, value: &str) -> Result<Shape, E>
where
E: de::Error,
{
match value {
"t" => Ok(Shape::Triangle),
"r" => Ok(Shape::Rectangle),
"p" => Ok(Shape::Pentagon),
_ => Err(de::Error::unknown_variant(value, VARIANTS)),
}
}
}
deserializer.deserialize_str(EnumVisitor)
}
}
#[derive(Debug, Deserialize)]
pub struct Post {
shape: Shape,
}
fn main() {
let data = r#"
{
"shape": "t"
}"#;
let p: Post = serde_json::from_str(data).unwrap();
dbg!(p);
}
@Mathspy
Copy link
Author

Mathspy commented Apr 4, 2020

Don't use this though, use this instead:

#[derive(Debug, Deserialize)]
enum Shape {
    #[serde(rename(deserialize = "t"))]
    Triangle = 3,
    #[serde(rename(deserialize = "r"))]
    Rectangle = 4,
    #[serde(rename(deserialize = "p"))]
    Pentagon = 5,
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment