gpt4 book ai didi

rust - 如何在自定义序列化和反序列化中使用 "flatten"之类的东西

转载 作者:行者123 更新时间:2023-12-05 04:36:35 26 4
gpt4 key购买 nike

我需要使用 SerializeDeserialize 的自定义实现,但我不知道如何做 #[serde(flatten)] 有没有人知道?

注意:我知道我可以将较低元素的完整实现完全重写到较高元素中,但较低元素实现了Serialize(和Deserialize),所以我正在寻找一种方法将其添加到 serialize_struct 之类的内容中。

#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Nested {
somefield2: String,
}

#[derive(Debug, PartialEq)]
struct TopLevel {
somefield1: usize,

nested: Nested,
}

impl Serialize for TopLevel {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// How to do this properly?
let mut do_struct = serializer.serialize_struct("Named", 2)?;
do_struct.serialize_field("somefield1", &self.somefield1)?;

// how to add everything from "self.nested" as the same level as this one?
// JSON example: { somefield1: 0, somefield2: 0 }

return do_struct.end();
}
}

impl<'de> Deserialize<'de> for TopLevel {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// Same question as in "Serialize", how to do this properly in here?
// Here is currently no example code, because i try to figure out "Serialize" first
todo!();
}
}

使用的版本:

  • 服务器端:1.0.133
  • 使用rust :1.58.1

注意:我已经阅读了Implementing Serialize并尝试搜索问题/stackoverflow,但找不到与此相关的任何内容。

最佳答案

您可以尝试为 Serialize 做类似的事情,为 Deserialize 做类似的事情:

struct FakeStructFlatteningSerializer<'a, SS: SerializeStruct>(&'a mut SS);

impl Serializer<'a, SS: SerializeStruct> for FakeStructFlatteningSerializer<'a, SS> {
type Ok = ();
type Error = SS::Error;
type SerializeStruct = FakeStructFlatteningSerializeStruct<'a, SS>;

// return Impossible for everything else

fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, Self::Error> {
// ignore name and len!
Ok(FakeStructFlatteningSerializeStruct(self.0))
}
}

struct FakeStructFlatteningSerializeStruct<'a, SS: SerializeStruct>(&'a mut SS);

impl<'a, SS: SerializeStruct> SerializeStruct for FakeStructFlatteningSerializeStruct<'a, SS> {
type Ok = ();
type Error = SS::Error;

fn serialize_field<T: Serialize + ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error> {
self.0.serialize_field(key, value)
}

fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
self.0.skip_field(key)
}

fn end(self) -> Result<Self::Ok, Self::Error> {
// ignore!
Ok(())
}
}



impl Serialize for TopLevel {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// len needs to include the flattened fields
let mut do_struct = serializer.serialize_struct("Named", 3)?;
do_struct.serialize_field("somefield1", &self.somefield1)?;
self.nested.serialize(FakeStructFlatteningSerializer(&mut do_struct));
return do_struct.end();
}
}

您也可以尝试弄清楚 Serde 是如何做到的;这可能是哪里:https://github.com/serde-rs/serde/blob/dc0c0dcba17dd8732cd8721a7ef556afcb04c6c0/serde_derive/src/ser.rs#L953-L1037 , https://github.com/serde-rs/serde/blob/fb2fe409c8f7ad6c95e3096e5e9ede865c8cfb49/serde_derive/src/de.rs#L2560-L2578

关于rust - 如何在自定义序列化和反序列化中使用 "flatten"之类的东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70800997/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com