使用Serde对数组或值数组进行自定义反序列化

时间:2018-11-13 11:56:48

标签: rust serde

我想构建一个自定义反序列化器,以将值数组的数组反序列化为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]]

2 个答案:

答案 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);
}