Make untagged enums work#253
Conversation
|
I came upon this issue and tried using the PR branch in my code. It seems to work as intended, but there are two issues.
use serde::Deserialize;
use ron;
#[derive(Deserialize)]
#[serde(untagged)]
enum Number {
Number(i32),
SelfReferencing(Box<Number>),
}
fn main() {
let _: Number = ron::de::from_str("This causes a stack overflow").unwrap();
} |
|
@torkleyy could you have a look, please? |
|
@halvnykterist This PR should not be merged. Instead, a new version should be written that implements this in a cleaner way. Maybe there is some way to use serde that I couldn't find. My first post describes the problems I faced. If not, the best solution would be to feed the input characters into a state machine as they are read in. The current implementation checks the same characters multiple times. The stack overflow is not ideal but does make sense. After all, there could be an infinite number of nested |
|
Issue has had no activity in the last 60 days and is going to be closed in 7 days if no further activity occurs |
When deserializing an untagged enum, serde uses deserialize_any. There is ambiguity, as we cannot know if a struct or an enum is expected. That ambiguity is resolved by serde if we just give it a JSON-like data structure.
When we encounter an lone identifier, it becomes a string. An identifier with parens after it becomes a singleton map.
Solves #217
Newtype pain
Id(Val)would be{"Id": "Val"}in JSON, but RON produces a one-element tuple instead. The only way to identify that case that I could think of is checking for commas, which unfortunately makes deserializing somewhat quadratic. It could be linear if this was done as a preprocessing pass.Is there a way to first read a tuple but then change it if it only has one element?
Failing test case
One of the tests (
ron/src/de/value.rs
Line 256 in 25aa1eb