Repository: serde-rs/json (language: rust)

Issue:
Error roundtripping (regression from 1.0.25 to 1.0.38)
We need to roundtrip an enum that has an element `Float(f32)`. That used to work with 1.0.25, but fails with 1.0.38. [This gist](https://gist.github.com/lutter/2820e2c98331d5b5b6b95d62912e2e0f) has complete code that demonstrates the problem.

What happens is that the enum can be turned into a `serde_json::Value`, but trying to get the enum back from that causes the error `invalid type: map, expected f32`.

This is somewhat urgent, as it keeps us from updating other dependencies that use newer versions of serde_json (and we really need to update those).

For completeness sake, here is the `serde_json::Value` that fails to parse back to a `Float(f32)` and the error from my test program:
```
[src/main.rs:20] serde_json::to_value(v).unwrap() = Object(
    {
        "data": Number(159.10000610351562),
        "type": String(
            "Float"
        )
    }
)
[src/main.rs:25] serde_json::from_value::<Value>(jv) = Err(
    Error("invalid type: map, expected f32", line: 0, column: 0)
)
```



Discussion / hints:

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 168a40df3..dd912d69c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,6 +22,7 @@ itoa = "0.4.3"
 ryu = "0.2"
 
 [dev-dependencies]
+automod = "0.1"
 compiletest_rs = { version = "0.3", features = ["stable"] }
 serde_bytes = "0.10"
 serde_derive = "1.0"
diff --git a/src/number.rs b/src/number.rs
index b6ff8ff77..70a8f6d65 100644
--- a/src/number.rs
+++ b/src/number.rs
@@ -473,7 +473,7 @@ macro_rules! deserialize_any {
             } else if let Some(i) = self.as_i64() {
                 return visitor.visit_i64(i);
             } else if let Some(f) = self.as_f64() {
-                if f.to_string() == self.n {
+                if ryu::Buffer::new().format(f) == self.n || f.to_string() == self.n {
                     return visitor.visit_f64(f);
                 }
             }


Test patch:
diff --git a/tests/regression.rs b/tests/regression.rs
new file mode 100644
index 000000000..eff29ff6c
--- /dev/null
+++ b/tests/regression.rs
@@ -0,0 +1,6 @@
+extern crate automod;
+extern crate serde;
+extern crate serde_derive;
+
+#[path = "regression/mod.rs"]
+mod regression;
diff --git a/tests/regression/issue520.rs b/tests/regression/issue520.rs
new file mode 100644
index 000000000..6befd494c
--- /dev/null
+++ b/tests/regression/issue520.rs
@@ -0,0 +1,18 @@
+use serde_derive::{Serialize, Deserialize};
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(tag = "type", content = "data")]
+enum E {
+    Float(f32),
+}
+
+#[test]
+fn test() {
+    let e = E::Float(159.1);
+    let v = serde_json::to_value(e).unwrap();
+    let e = serde_json::from_value::<E>(v).unwrap();
+
+    match e {
+        E::Float(f) => assert_eq!(f, 159.1),
+    }
+}
diff --git a/tests/regression/mod.rs b/tests/regression/mod.rs
new file mode 100644
index 000000000..830175fc2
--- /dev/null
+++ b/tests/regression/mod.rs
@@ -0,0 +1,1 @@
+automod::dir!("tests/regression");