C
C#•5mo ago
Playwo

Parse Rust Enum Json in C#

Rust enums are a cool feature for Rust devs, but now that I gotta parse them in C# I hate them. I got a JSON input that looks like this:
{
"Key": "DoesNotExist",
"Key2": {
"Position": 10
},
"Key3": {
"Order": {
"Id": 10,
"Name": "123"
}
}
}
{
"Key": "DoesNotExist",
"Key2": {
"Position": 10
},
"Key3": {
"Order": {
"Id": 10,
"Name": "123"
}
}
}
Key1, Key2, Key3 are 3 possible Enum values in Rust. But I cannot seem to find any reasonable way to parse this in C#. Yes I could write a JsonConverter for this simple case, in practice I am working on a source generator that has to work on any input where often times enums like this are nested in each other and having to create a JsonConverter for that entire tree is just pain :/
18 Replies
Pobiega
Pobiega•5mo ago
hm that json is an object with three properties - not a structure I'd expect for an object deserialized with a rust enum value on it
Playwo
Playwo•5mo ago
Well, some more context. The input for my source generator is a Json schema. The schema that allows for this JSON comes from an enum looking like this https://i.imgur.com/vR1DgE0.png
Imgur
Pobiega
Pobiega•5mo ago
Ah I see, so this is the schema and not an actual value that complicates things 😛
Playwo
Playwo•5mo ago
Yeah 😅
Pobiega
Pobiega•5mo ago
I was about to suggest using [JsonDerived] but that wont help here then
Playwo
Playwo•5mo ago
Yeah already looked at that. There isn't a clear discriminator to use here
Pobiega
Pobiega•5mo ago
exactly dunno if you can get around this without a custom converter then
Playwo
Playwo•5mo ago
Well only if I go and parse the entire tree with the custom converter. This is a simple case cause there's just primitives in the enum. But that is not a requirement, there can be more objects and more such enums inside one. And at that point complexity of the generator just explodes Not something I would be comfortable with generating in a source gen
Pobiega
Pobiega•5mo ago
true
Playwo
Playwo•5mo ago
Rust, why you gotta do this to me PepeHands
Pobiega
Pobiega•5mo ago
more like, C# why you no have proper DUs yet? but yeah, its an awkward structure to parse
Playwo
Playwo•5mo ago
I think I have something
Playwo
Playwo•5mo ago
Parse with JsonDocuments, then do some processing, but the processing is fairly minimal and most importantly low complexity so I can source generate that
Pobiega
Pobiega•5mo ago
Won't this also explode if the enums have complicated objects in them?
Playwo
Playwo•5mo ago
Hmm, probably At least the simple Deserialize call will not work Would have to call some variant of this recursively instead of calling that Deserialize there Performance Stinks
Playwo
Playwo•5mo ago
Adding a ok ish solution to this in case anyone stumbles across this later on: - Use the method I've sent above for doing the parsing from JsonDocument -> Enum type - Add a JsonConverter to the Enum type that looks like this https://i.imgur.com/fu9226J.png
Imgur
Playwo
Playwo•5mo ago
Only thing that differs between converters is the cases in the Write method. You'll want to manually map the cases of the enum that are just a string to that string instead of using the default converter Also you can ofc do something smarter than looking for that method via reflection on each Write just a PoC