У меня есть группа разных сообщений, которые поступают как JSON и могут быть выделены на основе одного поля, но тогда каждый вариант имеет различную коллекцию вторичных полей:
#[derive(Debug, Serialize, Deserialize)]
struct MessageOne {
///op will always be "one"
op: String,
x: f64,
y: f64,
}
#[derive(Debug, Serialize, Deserialize)]
struct MessageTwo {
///op will always be "two"
op: String,
a: f64,
b: i64,
}
Различные типы сообщений направляются различным функциям обработки (например, process_message_one
, process_message_two
и т. Д.). Есть ли элегантный или идиоматический способ автоматического выбора правильного подтипа сообщения? В настоящее время я определил общее сообщение:
#[derive(Debug, Serialize, Deserialize)]
struct MessageGeneric {
op: String,
}
затем проанализируйте входящий JSON в MessageGeneric
, прочтите поле op
и затем снова десериализуйте, сопоставив op
, чтобы выбрать правильный тип сообщения. Полный пример:
#![allow(unused)]
extern crate serde; // 1.0.78
extern crate serde_json; // 1.0.27
#[macro_use]
extern crate serde_derive;
use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize)]
struct MessageGeneric {
op: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct MessageOne {
///op will always be "one"
op: String,
x: f64,
y: f64,
}
#[derive(Debug, Serialize, Deserialize)]
struct MessageTwo {
///op will always be "two"
op: String,
a: f64,
b: f64,
}
fn process_message_one(m: &MessageOne) {
println!("Processing a MessageOne: {:?}", m);
}
fn process_message_two(m: &MessageTwo) {
println!("Processing a MessageTwo: {:?}", m);
}
fn main() {
let data = r#"{
"op": "one",
"x": 1.0,
"y": 2.0
}"#;
let z: MessageGeneric = serde_json::from_str(data).unwrap();
match z.op.as_ref() {
"one" => {
let zp: MessageOne = serde_json::from_str(data).unwrap();
process_message_one(&zp);
},
"two" => {
let zp: MessageTwo = serde_json::from_str(data).unwrap();
process_message_two(&zp);
},
_ => println!("Unknown Message Type")
}
}
Я видел представления перечисления Serde, но мне было неясно, будет ли / как это применяться в Это дело. Входящие сообщения определяются внешним API, поэтому я не могу контролировать их содержимое, не зная, какие есть варианты.