Reputation: 961
I'm trying to serialize a struct which has some Option
al enum fields to their default enum
variants.
By default
I mean the variant marked with the #[default]
serde attribute. However, this keeps on deserialising to null
instead of the default value.
Here's a simple example
use serde::{Deserialize, Serialize};
use serde_json;
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
struct Foo {
pub text: String,
#[serde(default)]
pub version: Option<Version>,
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub enum Version {
#[serde(rename = "PlayV1.0")]
PlayV1,
#[serde(rename = "PlayV2.0")]
#[default]
PlayV2,
}
fn main() {
let req = Foo {
text: "Hello, world!".to_string(),
..Default::default()
};
let json = serde_json::to_string(&req).unwrap();
println!("{}", json);
}
I have tried omitting the derive(Default)
from the enum
and instead, implementing my own e.g.
impl Default for Version {
fn default() -> Self {
Version::PlayV2
}
}
However I still get the following json
{"text":"Hello, world!","version":null}
What I'd like is this:
{"text":"Hello, world!","version": "PlayV2.0"}
I'm sure I'm missing something here or maybe this simply isn't even possible.
Upvotes: 0
Views: 668
Reputation: 27567
Moved here from the question:
So here's something that works as per Masklinn suggestion
use serde::{Deserialize, Serialize}; use serde_json; #[derive(Debug, Clone, Serialize, Deserialize)] struct Foo { pub text: String, #[serde(default)] pub version: Option<Version>, } impl Default for Foo { fn default() -> Self { return Foo { text: "".to_owned(), version: Some(Version::default()), }; } } #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub enum Version { #[serde(rename = "PlayV1.0")] PlayV1, #[serde(rename = "PlayV2.0")] #[default] PlayV2, } fn main() { let req = Foo { text: "Hello, world!".to_string(), ..Default::default() }; let json = serde_json::to_string(&req).unwrap(); println!("{}", json); }
Upvotes: 0
Reputation: 42592
I have tried omitting the derive(Default) from the enum and instead, implementing my own e.g.
That's the wrong default: Foo::default()
will invoke Option::default()
which is None
. So if you want to override the default value for the version
field you need to either remove the Option
so that the derived Foo::default
calls Version::default
, or impl Default for Foo
by hand.
Upvotes: 2