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:
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.