I'm trying to get the name of an enum variant as the string serde would expect/create. For example, say I have the following enum:
#[derive(Serialize, Deserialize)]
#[serde(rename_all="camelCase")]
pub enum SomeEnum {
WithoutValue,
withValue(i32),
}
How can I then get the serde names of the variants? Something like
serde::key_name(SomeEnum::WithoutValue) // should be `withoutValue`
serde::key_name(SomeEnum::WithValue) // should be `withValue`
I can use a hack with serde_json
, for variants without a value I can do:
serde_json::to_string(SomeEnum::WithoutValue).unwrap(); // yields `"withoutValue"` with quotation marks
This is not the best solution as I then need to strip the quotation marks, but can technically work.
Even worse is when the enum variant has a value. It becomes much messier.
serde_json::to_string(SomeEnum::WithValue(0)).unwrap(); // yields `"{\"second\":0}"
Is there a clean way to achieve this? I can't find a serde API to get key name as a string.
This representation is common in Java libraries. This representation works for struct variants, newtype variants containing structs or maps, and unit variants but does not work for enums containing tuple variants. Using a # [serde (tag = "...")] attribute on an enum containing a tuple variant is an error at compile time.
The default representation for this enum in Serde is called the externally tagged enum representation. Written in JSON syntax it looks like: {"Request": {"id": "...", "method": "...", "params": {...}}}
Only allowed on a newtype variant (a tuple variant with only one field). Deserialize this variant if the enum tag is anything other than the tag of one of the other variants in this enum. Only allowed on a unit variant inside of an internally tagged or adjacently tagged enum.
If you need to convert a string value to the enum type, then use Show activity on this post. Replace Your_ENUM_List in the code example with your ENUM and run this code. Show activity on this post. You may heard that enum.toString () has performance issue, so better to use nameof (enum.x), e.g nameof (ChangeFrequency.Always) will return "Always"
A stable yet somewhat boilerplate heavy way of extracting the variant information is by implementing a custom Serializer
which collects the variant names from the serialize_*_variant
functions.
This is the approach taken by serde_variant
. @Mendy mentioned that this crate only works for unit variants. This is the example in the readme.
use serde_variant::to_variant_name;
#[derive(Serialize)]
enum Foo {
Var1,
#[serde(rename = "VAR2")]
Var2,
}
assert_eq!(to_variant_name(&Foo::Var1).unwrap(), "Var1");
assert_eq!(to_variant_name(&Foo::Var2).unwrap(), "VAR2");
One other downside to mention is that this only works with the default, externally tagged enum representation. Other representations do not use the serialize_*_variant
functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With