Skip to content
This repository has been archived by the owner on Mar 25, 2024. It is now read-only.

#[serde(flatten)] disables treating an integer as a string #388

Open
espindola opened this issue Sep 5, 2023 · 0 comments
Open

#[serde(flatten)] disables treating an integer as a string #388

espindola opened this issue Sep 5, 2023 · 0 comments

Comments

@espindola
Copy link

In the following example the first struct deserializes , but the second one fails with "invalid type: integer 42, expected a string".

use serde::Deserialize;

#[derive(Deserialize)]
struct Inner {
    x: String,
}

#[derive(Deserialize)]
struct S {
    #[serde(flatten)]
    inner: Inner,
}

fn main() {
    let t = "x: 42";
    let v: Inner = serde_yaml::from_str(t).unwrap();
    println!("{}", v.x);

    let v: S = serde_yaml::from_str(t).unwrap();
    println!("{}", v.inner.x);
}
chris-olszewski added a commit to vercel/turborepo that referenced this issue Oct 30, 2023
### 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>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant