如何从原始结构反序列化结构的子字段';s JSON与Serde?

如何从原始结构反序列化结构的子字段';s JSON与Serde?,json,rust,serde,Json,Rust,Serde,我想从Test对象本身的数据中反序列化Test::team_size属性: #[derive(Debug, Serialize, Deserialize)] struct TeamSize { pub min: i64, pub max: i64, } #[derive(Debug, Serialize, Deserialize)] struct Test { pub i: i64, pub team_size: TeamSize, } fn main() {

我想从
Test
对象本身的数据中反序列化
Test::team_size
属性:

#[derive(Debug, Serialize, Deserialize)]
struct TeamSize {
    pub min: i64,
    pub max: i64,
}

#[derive(Debug, Serialize, Deserialize)]
struct Test {
    pub i: i64,
    pub team_size: TeamSize,
}

fn main() {
    let t: Test = serde_json::from_str(r#"{"i": -2, "min": 2, "max": 5}"#).unwrap();
    assert_eq!(t.i, -2);
    assert_eq!(t.team_size.min, 2);
    assert_eq!(t.team_size.max, 5);
}
这段代码没有编译,我不知道如何让Serde做我想做的事情。在本例中,有没有办法从作为子字段的原始结构的JSON反序列化
team_size

似乎我想要的是类似于的东西,但是对于一个结构和一个字段,而不是整个结构。

有一章介绍了当自动生成的属性不能完全满足您的要求时如何处理。从这里开始,它不是太复杂,只是单调乏味:

extern crate serde;
extern crate serde_json;

use std::fmt;

use serde::de::{self, Deserialize, Deserializer, Visitor, MapAccess};

#[derive(Debug)]
struct TeamSize {
    pub min: i64,
    pub max: i64,
}

#[derive(Debug)]
struct Test {
    pub i: i64,
    pub team_size: TeamSize,
}

impl<'de> Deserialize<'de> for Test {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        struct TestVisitor;

        impl<'de> Visitor<'de> for TestVisitor {
            type Value = Test;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("struct Test")
            }

            fn visit_map<V>(self, mut map: V) -> Result<Test, V::Error>
                where V: MapAccess<'de>
            {
                let mut min = None;
                let mut max = None;
                let mut i = None;

                while let Some(key) = map.next_key()? {
                    match key {
                        "min" => {
                            if min.is_some() {
                                return Err(de::Error::duplicate_field("min"));
                            }
                            min = Some(map.next_value()?);
                        }
                        "max" => {
                            if max.is_some() {
                                return Err(de::Error::duplicate_field("max"));
                            }
                            max = Some(map.next_value()?);
                        }
                        "i" => {
                            if i.is_some() {
                                return Err(de::Error::duplicate_field("i"));
                            }
                            i = Some(map.next_value()?);
                        }
                        _ => {
                            /* Ignore extra fields */
                        }
                    }
                }

                let min = min.ok_or_else(|| de::Error::missing_field("min"))?;
                let max = max.ok_or_else(|| de::Error::missing_field("max"))?;
                let i = i.ok_or_else(|| de::Error::missing_field("i"))?;

                Ok(Test { i, team_size: TeamSize { min, max }})
            }
        }

        const FIELDS: &'static [&'static str] = &["min", "max", "i"];
        deserializer.deserialize_struct("Test", FIELDS, TestVisitor)
    }
}

fn main() {
    let t: Test = serde_json::from_str(r#"{"i": -2, "min": 2, "max": 5}"#).unwrap();
    assert_eq!(t.i, -2);
    assert_eq!(t.team_size.min, 2);
    assert_eq!(t.team_size.max, 5);
}
extern板条箱系列;
外部板条箱serde_json;
使用std::fmt;
使用serde::de::{self,反序列化,反序列化器,访问者,MapAccess};
#[导出(调试)]
结构团队规模{
发布时间:i64,
pub max:i64,
}
#[导出(调试)]
结构测试{
第一酒吧:i64,
酒吧团队规模:团队规模,
}
impl测试{
fn反序列化(反序列化程序:D)->结果
其中D:反序列化程序访问者
{
设mut min=None;
设mut max=None;
设muti=None;
而让一些(键)=映射。下一个键(){
匹配键{
“min”=>{
如果min.是某个(){
返回Err(de::Error::重复的_字段(“min”);
}
min=Some(map.next_value()?);
}
“最大值”=>{
如果max.是某个(){
返回Err(de::Error::重复的_字段(“max”);
}
max=Some(map.next_value()?);
}
“我”=>{
如果我是某个人{
返回Err(de::Error::重复的_字段(“i”);
}
i=Some(map.next_value()?);
}
_ => {
/*忽略额外字段*/
}
}
}
让min=min.ok_或_else(| | de::Error::missing_字段(“min”)?;
设max=max.ok_或_else(| | de::Error::missing_字段(“max”)?;
设i=i.ok_或| else(| | de::Error::missing_字段(“i”)?;
Ok(测试{i,团队大小:团队大小{min,max}})
}
}
常量字段:&'static[&'static str]=&[“min”、“max”、“i”];
反序列化程序。反序列化结构(“测试”,字段,TestVisitor)
}
}
fn main(){
让t:Test=serde#u json::from_str(r#“{”i):-2,“min”:2,“max”:5}“#”).unwrap();
断言(t.i,-2);
断言(t.team_size.min,2);
断言(t.team_size.max,5);
}

从Serde 1.0.34开始,您现在可以使用:


在此之前,最简单的解决方法是反序列化为私有助手类型,并根据需要重新构造它:

#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

use serde::{Serialize, Serializer, Deserialize, Deserializer};

#[derive(Debug)]
pub struct TeamSize {
    pub min: i64,
    pub max: i64,
}

#[derive(Debug)]
pub struct Test {
    pub i: i64,
    pub team_size: TeamSize,
}

// Private helper
#[derive(Serialize, Deserialize)]
struct Helper {
    pub i: i64,
    pub min: i64,
    pub max: i64,
}

impl Serialize for Test {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        let helper = Helper {
            i: self.i,
            min: self.team_size.min,
            max: self.team_size.max,
        };
        helper.serialize(serializer)
    }
}

impl<'de> Deserialize<'de> for Test {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        let helper = Helper::deserialize(deserializer)?;
        Ok(Test {
            i: helper.i,
            team_size: TeamSize {
                min: helper.min,
                max: helper.max,
            },
        })
    }
}

fn main() {
    let j = r#" { "i": -2, "min": 2, "max": 5 } "#;

    let de: Test = serde_json::from_str(j).unwrap();
    println!("{:#?}", de);

    let ser = serde_json::to_string_pretty(&de).unwrap();
    println!("{}", ser);
}
#[宏使用]
外部板条箱serde_;
外部板条箱;
外部板条箱serde_json;
使用serde::{Serialize,Serializer,Deserialize,Deserializer};
#[导出(调试)]
发布结构团队大小{
发布时间:i64,
pub max:i64,
}
#[导出(调试)]
pub结构测试{
第一酒吧:i64,
酒吧团队规模:团队规模,
}
//私人佣工
#[派生(序列化、反序列化)]
结构辅助程序{
第一酒吧:i64,
发布时间:i64,
pub max:i64,
}
用于测试的impl序列化{
fn序列化(&self,序列化程序:S)->结果
其中S:序列化程序
{
让helper=helper{
我:赛尔夫,我,
min:self.team_size.min,
max:self.team_size.max,
};
serialize(序列化程序)
}
}
impl测试{
fn反序列化(反序列化程序:D)->结果
其中D:反序列化相关问题:
#[macro_use]
extern crate serde_derive;

extern crate serde;
extern crate serde_json;

use serde::{Serialize, Serializer, Deserialize, Deserializer};

#[derive(Debug)]
pub struct TeamSize {
    pub min: i64,
    pub max: i64,
}

#[derive(Debug)]
pub struct Test {
    pub i: i64,
    pub team_size: TeamSize,
}

// Private helper
#[derive(Serialize, Deserialize)]
struct Helper {
    pub i: i64,
    pub min: i64,
    pub max: i64,
}

impl Serialize for Test {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where S: Serializer
    {
        let helper = Helper {
            i: self.i,
            min: self.team_size.min,
            max: self.team_size.max,
        };
        helper.serialize(serializer)
    }
}

impl<'de> Deserialize<'de> for Test {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where D: Deserializer<'de>
    {
        let helper = Helper::deserialize(deserializer)?;
        Ok(Test {
            i: helper.i,
            team_size: TeamSize {
                min: helper.min,
                max: helper.max,
            },
        })
    }
}

fn main() {
    let j = r#" { "i": -2, "min": 2, "max": 5 } "#;

    let de: Test = serde_json::from_str(j).unwrap();
    println!("{:#?}", de);

    let ser = serde_json::to_string_pretty(&de).unwrap();
    println!("{}", ser);
}