我想构建一个自定义反序列化器来Vec<Child>将值数组的数组反序列化为Child.
一个想法是Vec<Child>直接添加一个客户解串器,但我想知道是否存在更优雅的解决方案。
作为一个例子,我正在尝试制作类似下面的内容,但array在 Parent 中使用字段而不是single.
extern crate serde_json; // 1.0.32
extern crate serde; // 1.0.80
#[macro_use] extern crate serde_derive;
use serde::de::{Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug, Deserialize)]
struct Parent {
#[serde(deserialize_with = "parse_child")]
single: Child,
//#[serde(deserialize_with = "parse_child")]
//array: Vec<Child>,
}
#[derive(Default, Debug, Deserialize)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn parse_child<'de, D>(deserializer: D) -> Result<Child, D::Error>
where
D: Deserializer<'de>,
{
struct ChildParser;
impl<'de> Visitor<'de> for ChildParser
{
type Value = Child;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[u64, f32, usize]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
println!("In custom deserializer");
let mut child = Child { ..Default::default() };
let tmp = seq.next_element::<u64>()?;
if let Some(a) = tmp {
child.a = a;
};
let tmp = seq.next_element::<f32>()?;
if let Some(b) = tmp {
child.b = b;
};
let tmp = seq.next_element::<usize>()?;
if let Some(c) = tmp {
child.c = c;
};
Ok(child)
}
}
deserializer.deserialize_any(ChildParser{})
}
fn main() {
let child_data = r#"[49, 11.75, 0]"#;
let child : Child = serde_json::from_str(child_data).unwrap();
println!("Child = {:?}", &child);
let parent_data = r#"{"single": [49, 11.75, 0]}"#;
let parent : Parent = serde_json::from_str(parent_data).expect("to be able to deserialize it");
println!("Parent = {:?}", &parent);
}
Run Code Online (Sandbox Code Playgroud)
链接到游乐场
我想要反序列化的示例输入:[[49, 11.75, 0], [42, 9, 1]]
我将其实现为:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
#[serde(transparent)]
struct Parent {
array: Vec<Child>,
}
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
println!("{:#?}", serde_json::from_str::<Parent>(j).unwrap());
}
Run Code Online (Sandbox Code Playgroud)
或者更简洁地说:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Deserialize, Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
fn main() {
let j = r#" [[49, 11.75, 0], [42, 9, 1]] "#;
let array: Vec<Child> = serde_json::from_str(j).unwrap();
println!("{:#?}", array);
}
Run Code Online (Sandbox Code Playgroud)