使用 Box 对结构实施反序列化

bru*_*uan 3 rust deserialization serde serde-json

包含 Box 作为成员变量的结构:

type Item = dyn Fn() -> Result<(), Box<dyn std::error::Error + Send + Sync>>;
struct Inner {
    pub data: Box<Item>,
}

// a function, like the type: Item
fn parse() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    println!("parse called");
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

Inner现在出现了自定义实现结构体反序列化的问题:

let s = r#"{"data": "parse"}"#;
Run Code Online (Sandbox Code Playgroud)

进入结构体内部:

{
    data: Box::new(parse)
}
Run Code Online (Sandbox Code Playgroud)

我知道serde不要实现 deserialize for ,并且必须手动实现 Deserialize ,这是我的代码,遵循docmentaionBox<T>给出的示例:

let s = r#"{"data": "parse"}"#;
Run Code Online (Sandbox Code Playgroud)

但是,当我运行这些代码时,出现错误:

{
    data: Box::new(parse)
}
Run Code Online (Sandbox Code Playgroud)

粗略地说,我猜问题出在(***)块上,但不知道如何解决它。如何正确实施Deserialize我的用例?

Sta*_*eur 5

该警告给了你一个提示:你没有使用数据,所以 Rust 不关心 Option 中的类型。实际上我很惊讶它正在编译。Rust 假定您期望(),因为 serdes 默认类型,而您期望String. 您的数据根本不会被消耗,所以只需执行以下操作:

\n
let mut data: Option<&str> = None;\n
Run Code Online (Sandbox Code Playgroud)\n

另外,我建议将所有Field实现替换为:

\n
#[derive(Deserialize)]\n#[serde(field_identifier, rename_all = "lowercase")]\nenum Field {\n    Data,\n}\n
Run Code Online (Sandbox Code Playgroud)\n

(这个堆栈在操场上由于未知原因溢出,但我预计这是操场的问题)

\n
\n

另外,您可以只使用deserialize_with

\n
use serde::{Deserialize, Deserializer};\n\ntype Item = dyn Fn() -> Result<(), Box<dyn std::error::Error + Send + Sync>>;\n#[derive(Deserialize)]\nstruct Inner {\n    #[serde(deserialize_with = "deserialize_data")]\n    pub data: Box<Item>,\n}\n\nfn deserialize_data<\'de, D>(d: D) -> Result<Box<Item>, D::Error>\nwhere\n    D: Deserializer<\'de>,\n{\n    let data = <&str>::deserialize(d)?;\n    println!("{}", data);\n    Ok(Box::new(parse))\n}\n\nfn parse() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {\n    println!("parse called");\n    Ok(())\n}\n\nfn main() {\n    let s = r#"{"data": "parse"}"#;\n    let inner: Inner = serde_json::from_str(s).unwrap();\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这要好得多,因为 serde 宏的实现可以比 na\xc3\xafve 实现做得更好。

\n