我想构建一个自定义反序列化器,以将值数组的数组反序列化为Vec<Child>
,其中我已经编写了一个自定义serde反序列化器,以将值数组解析为Child
。 / p>
一个想法是直接为Vec<Child>
添加一个客户反序列化器,但是我想知道是否会存在一个更优雅的解决方案。
作为说明,我正在尝试进行以下操作,但在Parent中使用字段array
而不是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);
}
链接到playground
我要反序列化的示例输入:[[49, 11.75, 0], [42, 9, 1]]
答案 0 :(得分:3)
我将其实现为:
#[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());
}
或更简洁地说:
#[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);
}
答案 1 :(得分:0)
我不确定这是否是您想要的,但是使用doc for deserialize a map:
extern crate serde; // 1.0.80
extern crate serde_json; // 1.0.32
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use std::fmt;
#[derive(Debug)]
struct Child {
a: u64,
b: f32,
c: usize,
}
struct ChildVisitor;
impl<'de> Visitor<'de> for ChildVisitor {
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 access: A) -> Result<Self::Value, A::Error> {
let a = access.next_element::<u64>()?.unwrap_or(Default::default());
let b = access.next_element::<f32>()?.unwrap_or(Default::default());
let c = access
.next_element::<usize>()?
.unwrap_or(Default::default());
Ok(Child { a, b, c })
}
}
impl<'de> Deserialize<'de> for Child {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ChildVisitor {})
}
}
#[derive(Debug)]
struct Parent {
childs: Vec<Child>,
}
struct ParentVisitor {}
impl<'de> Visitor<'de> for ParentVisitor {
type Value = Parent;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("[[Child]]")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
let mut childs = Vec::with_capacity(access.size_hint().unwrap_or(0));
while let Some(child) = access.next_element::<Child>()? {
childs.push(child);
}
Ok(Parent { childs })
}
}
impl<'de> Deserialize<'de> for Parent {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ParentVisitor {})
}
}
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#"[[49, 11.75, 0], [42, 9, 1]]"#;
let parent: Parent = serde_json::from_str(parent_data).unwrap();
println!("Parent = {:#?}", parent);
}