-
-
Notifications
You must be signed in to change notification settings - Fork 151
Hint to deserialize number as a string instead, inside untagged enum #165
Comments
I can't reproduce this. Next time please provide a minimal compilable code example when opening an issue. use serde::Deserialize;
use std::collections::BTreeMap;
#[derive(Deserialize, Debug)]
struct Foo {
foos: BTreeMap<String, usize>,
}
const Y: &str = "
foos:
bar: 42
baz: 123
200: 321";
fn main() {
println!("{:#?}", serde_yaml::from_str::<Foo>(Y).unwrap());
} Foo {
foos: {
"200": 321,
"bar": 42,
"baz": 123,
},
} |
@dtolnay sorry for the long wait, it took me a bit of debugging to get my complex example down to a minimal reproducible case. It looks like this problem only happens when an untagged enum is involved. Here's the code (playgound link):
|
@dtolnay any chance you could take a look at this? |
I have not gotten a chance, but I would accept a PR if there is a fix in serde_yaml. |
i have a similar problem whereby I am storing a semantic version or version range in a yaml field. Examples:
I ended up creating an enum with something like:
so that it would deserialize. I then implemented various convenience traits to make it simpler to work with. However, I would love to be able to decorate the field with a type hint that makes it deserialize to a String. |
Change your example to:
and you'll see the problem we're facing: you'll end up with |
Here is a minimal example of a similar issue, but instead caused by the use of Is it possible this has the same root cause? The functionality of |
Another option to resolving this is perhaps to implement a RawValue API for serde_yaml similar to that of serde_json which would surface the raw string for parsing. Some yaml users (looking at you yarn) do not know how to properly quote their strings and RawValue while more verbose would give a general-purpose escape hatch to deal with this. |
### Description Fixes #6232 This PR allows us to properly deserialize semver versions from YAML in `yarn.lock`. Previously we would fail at parsing ranges with trailing zeros e.g. `(0.10f32).to_string() == "0.1"`. The approach taken in this PR is due to some outstanding quirks in `serde_yaml`: - dtolnay/serde-yaml#165 (comment) - dtolnay/serde-yaml#388 Our usage of `#[serde(flatten)]` in `LockfileData` caused attempting to parse `2` or `0.10` as a `String` to fail. To avoid this we first parse the document as a map with a union of the metadata/package entries and then convert this to the expected structure. This provides us the type safety of the old implementation, but at the cost of rebuilding the map. As a minor thing, I removed all unused `Serialize`/`Deserialize` implementations to make it clear which codepaths actually get used. ### Testing Instructions Existing unit tests pass. I changed out the old unit tests for `SemverString` to be captured by the new `berry_semver.lock` test fixture which covers the same cases. We do this because even if parsing versions works when invoked directly, adding `#[serde(flatten)]`/`#[serde(untagged)]` to any containing structure changes the behavior. Closes TURBO-1540 --------- Co-authored-by: Chris Olszewski <Chris Olszewski>
I have a data structure like this:
And sometimes, the keys for that map can be numbers, but I'd like them deserialized as strings like the other keys.
For example:
I'd like to end up with
but instead I, understandably, get a deserialization erorr since
200
is a number.Is there any way to hint to
serde_yaml
that the200
should be deserialized as a string, or do I need to make a new type that performs these conversions in it'sDeserialize
impl?The text was updated successfully, but these errors were encountered: