我有一个 struct Foo
,我想将其序列化为 JSON 中的一个由两部分组成的字符串,例如"01abcdef:42"
,但在 bincode 中正常。
(由于大小原因,我需要它在 bincode 中正常序列化。在某些情况下,Bar
或 Baz
是大型字节数组,占用两倍以上的空间十六进制。)
我当前的代码正是我想要的:
pub struct Foo {
pub bar: Bar,
pub baz: Baz
}
impl<'de> ::serde::Deserialize<'de> for Foo {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Foo, D::Error> {
use ::serde::de::Error;
use core::str::FromStr;
if d.is_human_readable() {
let sl: &str = ::serde::Deserialize::deserialize(d)?;
Foo::from_str(sl).map_err(D::Error::custom)
} else {
let clone: FooClone = FooClone::deserialize(d)?;
Ok(Foo { bar: clone.bar, baz: clone.baz })
}
}
}
#[derive(Deserialize)]
pub struct FooClone {
pub bar: Bar,
pub baz: Baz
}
我需要手动维护 FooClone
作为 Foo
的相同副本。
我已阅读 this但与此结构克隆相比,需要维护的代码要多得多。
我怎样才能既手动实现Deserialize
(以处理 JSON 两部分字符串)又为相同结构派生Deserialize
(消除 FooClone
)?
最佳答案
像这样的东西应该可以工作。您仍然使用 derive 生成 deserialize
函数。但由于它是远程派生,因此该类型不会实现 Deserialize
,但会获得一个固有函数,您可以在手动 Deserialize
实现中调用该函数。
#[derive(serde::Deserialize)]
#[serde(remote = "Self")]
pub struct Foo {
pub bar: Bar,
pub baz: Baz,
}
impl<'de> ::serde::Deserialize<'de> for Foo {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Foo, D::Error> {
use ::serde::de::Error;
use core::str::FromStr;
if d.is_human_readable() {
let sl: &str = ::serde::Deserialize::deserialize(d)?;
Foo::from_str(sl).map_err(D::Error::custom)
} else {
Foo::deserialize(d)
}
}
}
关于rust - 如何同时实现反序列化和派生它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67543624/