See this use case.
Would the internally tagged enum support allow me to handle schema versioning defined like this?
{ "schema_version": 1, ... }I've never gotten a good answer about how I'd do that with Serde.
cc @ssokolow
Attributes support non-string literals now right? This could be as simple as allowing:
#[derive(Serialize, Deserialize)]
#[serde(tag = "schema_version")]
enum E {
#[serde(rename = 1)]
V1(...),
#[serde(rename = 2)]
V2(...),
}
Also boolean tags?
#[derive(Serialize, Deserialize)]
#[serde(tag = "error")]
enum Response {
#[serde(rename = false)]
Ok(QueryResult),
#[serde(rename = true)]
Err(QueryError),
}
Any plans to progress on this feature? I could give it a try, but I would need a bit of mentoring / pointing to the right places.
I have not started working on this. I would love a PR! Happy to provide guidance if you run into any trouble.
Any updates on this?
Hi :smile:
We need this feature for sozu #240 to handle configuration versioning.
I'd like to implement it. I saw that someone (#973) started working on it but abandoned it.
Can I use it as a starting point or do you recommend another approach ?
@NotBad4U You can use a string tag (the version enum's variant name) for the configuration version.
@NotBad4U I think #973 is the right approach. Literals in attributes will be stable in rust 1.30 so we can support #[serde(rename = 0)].
I guess this is blocked on https://github.com/serde-rs/serde/pull/1392?
For what it's worth, I think there's an additional use case for this (though it's technically not for internally tagged enums, it'd hopefully be fixed the same way): #[repr(i32)] enums and the like.
Right now my solution is https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=9154cf599592144c4473903b57d91abe ; but that's an awful lot of boilerplate for this simple use case :)
@Ekleog: I was able to use the serde_repr crate suggested by official docs to shorten your playground to this:
//! ```cargo
//! [dependencies]
//! serde = "1"
//! serde_repr = "0.1"
//! serde_json = "1"
//! ```
use std::fmt;
#[derive(Copy, Clone, Debug, serde_repr::Serialize_repr, serde_repr::Deserialize_repr)]
#[repr(i32)]
pub enum Test {
Foo = 0,
Bar = 2,
}
fn main() {
println!("{}", serde_json::to_string(&Test::Foo).unwrap());
println!("{:?}", serde_json::from_str::<Test>("0").unwrap());
}
This looks cool! I hadn't seen that in the docs when writing that message. Thank you!
Most helpful comment
Attributes support non-string literals now right? This could be as simple as allowing: