Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Inconsistent JSON output when serializing enums in Rust

I’m using serde_json to serialize an enum to JSON.
This is what I’m getting when serializing std::net::IpAddr:

use std::net::IpAddr;

fn main() {
    let addr : IpAddr = "127.0.0.1".parse().unwrap();
    let json = serde_json::to_string(&addr).unwrap();
    println!("{}", json);
}

output:

"127.0.0.1"

However, when I write my own similar enum and serialize it, it looks different:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
enum Foo {
    One(String),
    Two(String),
}

fn main() {
    let foo = Foo::One("one".to_string());
    let json = serde_json::to_string(&foo).unwrap();
    println!("{}", json);
}

output:

{"One":"one"}

Why does the first snippet write a JSON string while the second one writes a JSON object?

>Solution :

That’s because the impl Serialize for IpAddr isn’t derived but written like this:

impl Serialize for net::IpAddr {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        if serializer.is_human_readable() {
            match *self {
                net::IpAddr::V4(ref a) => a.serialize(serializer),
                net::IpAddr::V6(ref a) => a.serialize(serializer),
            }
        } else {
            match *self {
                net::IpAddr::V4(ref a) => {
                    serializer.serialize_newtype_variant("IpAddr", 0, "V4", a)
                }
                net::IpAddr::V6(ref a) => {
                    serializer.serialize_newtype_variant("IpAddr", 1, "V6", a)
                }
            }
        }
    }
}

Note especially the is_human_readable() branch where it just delegates to the Serialize implementations of the respective inner types and doesn’t add anything for the variant.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading