Hello people,
i am having problems with serde (deserialization).
here's the playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c684bca43433c2dcabc6c4209f4a6e5f
i did put some comments in line 57
Basically I can't get the two json strings to work (one requires a custom deserializer, and in the other one i don't need the custom deserializer but it appear to be forced).
Can someone enlighten me on what I should do?
Thanks
#[macro_use]
extern crate serde_derive;
use serde_json::Result;
fn main() -> Result<()> {
/*
if let Data::Pusher {
activity_timeout,
socket_id,
} = response.data
{
println!("{:#?}", activity_timeout);
};
*/
/*
println!("{:#?}", response.data);
let data3 = r#"
{
"data": [
["109.00000", "0.02563590"],
["109.00000", "0.03673540"]
],
"event": "updated"
}"#;
let response: Response = serde_json::from_str(data3)?;
println!("{:#?}", response);
if let Data::Updated(a) = response.data {
println!("{:#?}", a.first());
};
*/
let data4 = r#"
{"data":"{\"activity_timeout\":120,\"socket_id\":\"blalba\"}","event":"pusher:connection_established"}
"#;
let response: Response = serde_json::from_str(data4)?;
println!("{:#?}", response);
let data5 = r#"
{"channel":"test","event":"test:subscription_succeeded", "data": {}}
"#;
let response: Response = serde_json::from_str(data5)?;
println!("{:#?}", response);
Ok(())
}
#[derive(Deserialize, Debug)]
pub struct Response {
event: String,
// problem: data5 fails even if 'skip_serializing_if = "Map::is_empty"' is set
// apparently the error comes from json_string
#[serde(default, skip_serializing_if = "Map::is_empty", with = "json_string")]
pub data: Option<Data>,
}
use std::collections::HashMap;
#[derive(Deserialize, Debug)]
#[serde(untagged)]
pub enum Data {
Pusher {
activity_timeout: u32,
socket_id: String,
},
Updated(Vec<[String; 2]>),
}
mod json_string {
use serde::de::{self, Deserialize, DeserializeOwned, Deserializer};
use serde::ser::{self, Serialize, Serializer};
use serde_json;
pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: Serialize,
S: Serializer,
{
let j = serde_json::to_string(value).map_err(ser::Error::custom)?;
j.serialize(serializer)
}
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: DeserializeOwned,
D: Deserializer<'de>,
{
let j = String::deserialize(deserializer)?;
serde_json::from_str(&j).map_err(de::Error::custom)
}
}
Output:
Response {
event: "pusher:connection_established",
data: Some(
Pusher {
activity_timeout: 120,
socket_id: "blalba",
},
),
}
Errors:
Compiling playground v0.0.1 (/playground)
warning: unused import: `std::collections::HashMap`
--> src/main.rs:61:5
|
61 | use std::collections::HashMap;
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: function is never used: `serialize`
--> src/main.rs:78:12
|
78 | pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
| ^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 2 warnings emitted
Finished dev [unoptimized + debuginfo] target(s) in 1.05s
Running `target/debug/playground`
Error: Error("invalid type: map, expected a string", line: 2, column: 73)