serde
serde copied to clipboard
Deserialize "unknown" values
Hi there!
I'm a rust newbie so maybe I'm missing something but I've following problem:
I'm using serde to deserialize JSON response into struct
#[derive(Debug, Deserialize)]
struct Message {
channel: String,
global_id: u128,
message_id: i8,
data: ???, <--- this could be different types
}
API that I'm working with can return different type for data attribute, for example:
// first example
[
{
"global_id": -1,
"message_id": -1,
"channel": "/__status",
"data": {
"/channel": 3
}
}
]
// second example
[
{
"global_id": 1510,
"message_id": 3,
"channel": "/channel",
"data": "test"
}
]
// third example
[
{
"global_id": 1510,
"message_id": 3,
"channel": "/channel",
"data": {
"name": "Serde"
}
}
]
How can I represent this data attribute on the Message struct to accomodate this use-case?
✌️
@dixpac hello! Maybe this will help?
use serde_json::Value;
#[derive(Debug, Deserialize)]
struct Message {
channel: String,
global_id: u128,
message_id: i8,
data: Value,
}
Example:
use serde_json::Value;
use serde::Deserialize;
const A1: &'static str = r#"
{
"global_id": -1,
"message_id": -1,
"channel": "/__status",
"data": {
"/channel": 3
}
}
"#;
const A2: &'static str = r#"
{
"global_id": -1,
"message_id": -1,
"channel": "/__status",
"data": "test"
}
"#;
const A3: &'static str = r#"
{
"global_id": -1,
"message_id": -1,
"channel": "/__status",
"data": {
"name": 3
}
}
"#;
#[derive(Debug, Deserialize)]
struct Message {
channel: String,
global_id: i8,
message_id: i8,
data: Value,
}
fn main() {
let a1: Message = serde_json::from_str(A1).unwrap();
let a2: Message = serde_json::from_str(A2).unwrap();
let a3: Message = serde_json::from_str(A3).unwrap();
println!("{:?}", a1); // Message { channel: "/__status", global_id: -1, message_id: -1, data: Object({"/channel": Number(3)}) }
println!("{:?}", a2); // Message { channel: "/__status", global_id: -1, message_id: -1, data: String("test") }
println!("{:?}", a3); // Message { channel: "/__status", global_id: -1, message_id: -1, data: Object({"name": Number(3)}) }
}