- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 817
Flatten + deserialize_with generates incorrect Deserialize code #1240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Fixed in cb2b92f. |
Seem related, playground. use std::collections::HashMap;
use std::fmt;
use std::str::FromStr;
use serde; // 1.0.85
use serde::de::{self, Deserialize, MapAccess, Visitor}; // 1.0.85
use serde::Deserializer;
use serde_derive::Deserialize; // 1.0.85
use toml; // 0.4.10
use void::Void; // 1.0.2
#[derive(Debug)]
struct Obj {
x: isize,
y: String,
}
struct ObjVisitor;
#[derive(Debug, Deserialize)]
struct ObjAux {
x: isize,
y: String,
}
impl<'de> Visitor<'de> for ObjVisitor {
type Value = Obj;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("string or map")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(FromStr::from_str(value).unwrap())
}
fn visit_map<M>(self, visitor: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let aux: ObjAux = Deserialize::deserialize(de::value::MapAccessDeserializer::new(visitor))?;
Ok(Obj { x: aux.x, y: aux.y })
}
}
impl<'de> Deserialize<'de> for Obj {
fn deserialize<D>(deserializer: D) -> Result<Obj, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_any(ObjVisitor)
}
}
impl FromStr for Obj {
type Err = Void;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(Obj {
x: 0,
y: s.to_owned(),
})
}
}
#[derive(Debug, Deserialize)]
struct Simple {
obj: Obj,
}
#[derive(Debug, Deserialize)]
struct InsideHashMap {
objs: HashMap<String, Obj>,
}
fn main() {
// Basic deserialization of Obj
let toml = r#"
x = 5
y = "hello"
"#;
let obj: Obj = toml::from_str(toml).unwrap();
println!("{:?}", obj);
// Basic deserialization of Obj as a field in a struct
let toml = r#"
[obj]
x = 5
y = "hello"
"#;
let simple: Simple = toml::from_str(toml).unwrap();
println!("{:?}", simple);
// Basic deserialization of Obj as a field in a struct as a string or struct
let toml = r#"
obj = "hello"
"#;
let simple: Simple = toml::from_str(toml).unwrap();
println!("{:?}", simple);
// Deserialization of an Obj inside a HashMap
let toml = r#"
[objs]
a = { x = 5, y = "hello" }
"#;
let working: InsideHashMap = toml::from_str(toml).unwrap();
println!("{:?}", working);
// Deserialization of Obj inside a HashMap field as a string or struct
let toml = r#"
[objs]
a = "hello"
"#;
let not_working: InsideHashMap = toml::from_str(toml).unwrap();
println!("{:?}", not_working);
} Look like |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The following flattened field needs to invoke our deserialize_with function, not Point::deserialize.
Sub-issue of #1239.
The text was updated successfully, but these errors were encountered: