Json 如何将所有字段都是默认值的类型反序列化为None?

Json 如何将所有字段都是默认值的类型反序列化为None?,json,rust,serde,serde-json,Json,Rust,Serde,Serde Json,我必须反序列化JSON blob,在某些地方,缺少整个对象的情况被编码为具有相同结构的对象,但其所有字段都设置为默认值(空字符串和零) extern板条箱serde_json;//1.0.27 #[宏使用]外部板条箱服务器;//1.0.78 外部板条箱服务器;//1.0.78 #[派生(调试、反序列化)] 结构测试{ 文本:T, 编号:i32, } #[派生(调试、反序列化)] 结构外部{ 测试:选项, } #[派生(调试、反序列化)] enum Foo{Bar,Baz} #[派生(调试、反序列

我必须反序列化JSON blob,在某些地方,缺少整个对象的情况被编码为具有相同结构的对象,但其所有字段都设置为默认值(空字符串和零)

extern板条箱serde_json;//1.0.27
#[宏使用]外部板条箱服务器;//1.0.78
外部板条箱服务器;//1.0.78
#[派生(调试、反序列化)]
结构测试{
文本:T,
编号:i32,
}
#[派生(调试、反序列化)]
结构外部{
测试:选项,
}
#[派生(调试、反序列化)]
enum Foo{Bar,Baz}
#[派生(调试、反序列化)]
结构外部2{
测试:选项,
}
fn main(){
println!(“{:?}”,serde_json::from_str::(r#“{”test:{”text:“abc”,“number::42}}”).unwrap();
//好:外部{测试:一些(测试{文本:“abc”,编号:42})}
println!(“{:?}”,serde_json::from_str::(r#“{”test:null}”).unwrap();
//好:外部{测试:无}
println!(“{:?}”,serde_json::from_str::(r#“{”test:{”text:“,“number”:0}}}”).unwrap();
//错误:外部{test:Some(test{text:,number:0})
//应该是:外部{test:None}
println!(“{:?}”,serde_json::from_str::(r#“{”test:{”text:“Bar”,“number”:42}}}”).unwrap();
//好:Outer2{test:Some(test{text:Bar,number:42})}
println!(“{:?}”,serde_json::from_str::(r#“{”test:{”text:“,“number”:0}}}”).unwrap();
//错误:错误
//应该是:外部{test:None}
}
我将在反序列化后处理此问题,但正如您所看到的,这种方法不可能用于枚举值:没有变量匹配空字符串,因此反序列化完全失败

我怎样才能教塞德这个呢?

你可以看看

特别是,您可能需要定义如下内容

extern crate serde; // 1.0.78
#[macro_use]
extern crate serde_derive; // 1.0.78

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

fn none_if_all_default<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
where
    T: Deserialize<'de>,
    D: Deserializer<'de> + Clone,
{
    struct AllDefault;

    impl<'de> Visitor<'de> for AllDefault {
        type Value = bool;

        // Implement the visitor functions here -
        // You can recurse over all values to check if they're
        // the empty string or 0, and return true
        //...
    }

    let all_default = deserializer.clone().deserialize_any(AllDefault)?;

    if all_default {
        Ok(None)
    } else {
        Ok(Some(T::deserialize(deserializer)?))
    }
}
extern板条箱服务器;//1.0.78
#[宏_使用]
外部板条箱serde_derive;//1.0.78
使用serde::{反序列化,反序列化,de::Visitor};
fn无\u如果\u全部\u默认,

D:反序列化器访问者请增强您的示例,以演示如何按照OP的要求将其用于枚举。我无法让自己的示例使用枚举。由于
未实现所有trait项,此项也无法编译,缺少:`expecting`
。它无法编译,因为它不打算编译-这是一个基本答案,实现trait是手动工作,可以通过参考文档来完成。重点是展示解决OP问题的高层次思想。这适用于
enum
字段,因为它适用于属于
选项的任何字段。。一旦它消失了,如何调用
T::反序列化
?函数的返回类型不一致(
Result::Ok
vs.
Option::Some
)。此答案无效。反序列化程序。请注意,这就是为什么强烈鼓励您在回答之前创建一个有效的解决方案。
extern crate serde; // 1.0.78
#[macro_use]
extern crate serde_derive; // 1.0.78

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

fn none_if_all_default<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
where
    T: Deserialize<'de>,
    D: Deserializer<'de> + Clone,
{
    struct AllDefault;

    impl<'de> Visitor<'de> for AllDefault {
        type Value = bool;

        // Implement the visitor functions here -
        // You can recurse over all values to check if they're
        // the empty string or 0, and return true
        //...
    }

    let all_default = deserializer.clone().deserialize_any(AllDefault)?;

    if all_default {
        Ok(None)
    } else {
        Ok(Some(T::deserialize(deserializer)?))
    }
}
#[derive(Deserialize)]
struct Outer2 {
    #[serde(deserialize_with = "none_if_all_default")]
    test: Option<Test<Foo>>,
}