Rust 使用Serde自定义反序列化数组或值数组

Rust 使用Serde自定义反序列化数组或值数组,rust,serde,Rust,Serde,我想构建一个自定义反序列化程序,将值数组反序列化为Vec,其中我已经编写了一个自定义serde反序列化程序,用于将值数组解析为子项 一个想法是直接为Vec添加一个客户反序列化器,但我想知道是否存在一个更优雅的解决方案 作为一个例子,我试图制作如下内容,但在父项中使用字段数组,而不是单个 extern crate serde_json; // 1.0.32 extern crate serde; // 1.0.80 #[macro_use] extern crate serde_derive;

我想构建一个自定义反序列化程序,将值数组反序列化为
Vec
,其中我已经编写了一个自定义serde反序列化程序,用于将值数组解析为
子项

一个想法是直接为
Vec
添加一个客户反序列化器,但我想知道是否存在一个更优雅的解决方案


作为一个例子,我试图制作如下内容,但在父项中使用字段
数组
,而不是
单个

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);

}
extern板条箱serde_json;//1.0.32
外部板条箱服务器;//1.0.80
#[宏使用]外部板条箱服务器;
使用serde::de::{反序列化程序,SeqAccess,Visitor};
使用std::fmt;
#[派生(调试、反序列化)]
结构父级{
#[serde(用=“parse_child”反序列化)]
单身:孩子,
//#[serde(用=“parse_child”反序列化)]
//数组:Vec,
}
#[派生(默认、调试、反序列化)]
结构子对象{
a:u64,
b:f32,
c:使用,
}
fn parse_child,
{
结构儿童语法分析器;
儿童语法分析器的impl
{
类型值=子项;
fn预期(&self,格式化程序:&mut fmt::formatter)->fmt::Result{
格式化程序。write_str(“[u64,f32,usize]”)
}
fn访问


我想反序列化的示例输入:
[[49,11.75,0],[42,9,1]

我不确定这是否是您想要的,但使用:

extern板条箱服务器;//1.0.80
外部板条箱serde_json;//1.0.32
使用serde::de::{反序列化,反序列化程序,SeqAccess,Visitor};
使用std::fmt;
#[导出(调试)]
结构子对象{
a:u64,
b:f32,
c:使用,
}
结构儿童访客;
儿童看护{
类型值=子项;
fn预期(&self,格式化程序:&mut fmt::formatter)->fmt::Result{
格式化程序。write_str(“[u64,f32,usize]”)
}
fn访问顺序反序列化,
{
反序列化程序。反序列化_seq(ChildVisitor{})
}
}
#[导出(调试)]
结构父级{
孩子们:Vec,
}
结构ParentVisitor{}
家长来访者的请求{
类型值=父项;
fn预期(&self,格式化程序:&mut fmt::formatter)->fmt::Result{
格式化程序。写入\u str(“[[Child]]”)
}
fn访问顺序反序列化,
{
反序列化程序。反序列化_seq(ParentVisitor{})
}
}
fn main(){
让child_data=r#“[49,11.75,0]”;
让child:child=serde_json::from_str(child_data).unwrap();
println!(“Child={:#?}”,Child);
让parent_data=r#“[[49,11.75,0],[42,9,1]]”;
让parent:parent=serde_json::from_str(parent_data).unwrap();
println!(“父项={:#?}”,父项);
}

我将通过以下方式实现这一点:

#[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());
}
#[宏使用]
外部板条箱serde_;
外部板条箱;
外部板条箱serde_json;
#[派生(反序列化、调试)]
#[serde(透明)]
结构父级{
数组:Vec,
}
#[派生(反序列化、调试)]
结构子对象{
a:u64,
b:f32,
c:使用,
}
fn main(){
设j=r#“[[49,11.75,0],[42,9,1]]”;
println!(“{:}”,serde_json::from_str::(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);
}
#[宏使用]
外部板条箱serde_;
外部板条箱;
外部板条箱serde_json;
#[派生(反序列化、调试)]
结构子对象{
a:u64,
b:f32,
c:使用,
}
fn main(){
设j=r#“[[49,11.75,0],[42,9,1]]”;
让数组:Vec=serde_json::from_str(j).unwrap();
println!(“{:#?}”,数组);
}

@Stargateur你来了。你知道我怎么解决这个问题吗?好得多,但你的问题还不清楚。我们不知道你是否想反序列化
r#“{”single:[49,11.75,0]}”35;
r#“[[49,11.75,0],[42,9,1]]”#
或两者都反序列化。让家长:Vec=serde json::from#u str(parent_data).unwrap()
?谢谢@Stargateur确实我只需要为
手动实现
反序列化
,而不是派生它很多@dtolnay这确实是一个非常简洁的方法。我不知道(或不理解)serde可以直接从数组反序列化struct,我建议将
透明
示例添加到链接副本中。
#[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);
}