rust 使用serde,如何在反序列化时保留序列化数据的副本?

j8ag8udp  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(144)

我使用的是Rust和Serde。假设我有一个结构体,它希望保留创建它的JSON数据的副本,也许这样它就可以在其他地方重新发送相同的JSON而不必重新序列化。(这并不像保留原始JSON数据的副本那么简单,因为结构体可能包含更多的JSON数据。)示例:

#[derive(Deserialize)]
struct LargerStruct {
    value: i32,
    inner: InnerStruct,
}

#[derive(Deserialize)]
struct InnerStruct {
    this_json: String,
    inner_value: i32,
}

fn main() {
    let json = r#"
        {
          "value": 42, 
          "inner": { "inner_value": 100 }
        }
    "#;

    let val: LargerStruct = // ???

    assert_eq!(&val.inner.this_json, r#"{ "inner_value": 100 }"#);
}

???的评论可以用什么来填充?

lhcgjxsq

lhcgjxsq1#

/*
[dependencies]
serde.version = "*"
serde.features = ["derive"]
serde_json.version = "*"
serde_json.features = ["raw_value"]
*/

use serde::*;
use serde_json::value::RawValue;

#[derive(Deserialize)]
struct LargerStruct {
    value: i32,
    inner: InnerStruct,
}

struct InnerStruct {
    this_json: String,
    inner_value: i32,
}

impl<'de> Deserialize<'de> for InnerStruct {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        let this_json: Box<RawValue> = Deserialize::deserialize(deserializer)?;

        #[derive(Deserialize)]
        struct InnerStruct {
            inner_value: i32,
        }
        let this: InnerStruct =
            serde_json::from_str(this_json.get()).map_err(serde::de::Error::custom)?;

        Ok(Self{
            this_json: this_json.get().to_string(),
            inner_value: this.inner_value,
        })
    }
}

fn main() {
    let json = r#"
        {
          "value": 42, 
          "inner": { "inner_value": 100 }
        }
    "#;

    let val: LargerStruct = serde_json::from_str(json).unwrap();

    assert_eq!(&val.inner.this_json, r#"{ "inner_value": 100 }"#);
}

Playground
您可以使用serde_json::value::RawValue类型以原始形式捕获原始JSON。代码使用InnerStruct的自定义Deserialize实现来实现捕获JSON并反序列化的目标。它通过在Deserialize实现中再次调用serde_json来反序列化结构体。这是必要的,因为deserializer在解串RawValue之后被消耗。

相关问题