Serde 衍生宏具有通过
一个不幸过于矫揉造作的例子:(原文链接)。
#[serde(with = "module")]
字段属性控制字段序列化/反序列化的能力。其中 "module"
应该具有正确参数和返回类型的序列化和反序列化函数。一个不幸过于矫揉造作的例子:(原文链接)。
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, PartialEq, Eq)]
pub struct StringPair(String, String);
mod stringpair_serde {
pub fn serialize<S>(sp: &super::StringPair, ser: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
ser.serialize_str(format!("{}:{}", sp.0, sp.1).as_str())
}
pub fn deserialize<'de, D>(d: D) -> Result<super::StringPair, D::Error>
where
D: serde::Deserializer<'de>,
{
d.deserialize_str(Visitor)
}
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = super::StringPair;
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "a pair of strings separated by colon (:)")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(s.split_once(":")
.map(|tup| super::StringPair(tup.0.to_string(), tup.1.to_string()))
.unwrap_or(Default::default()))
}
}
}
#[derive(Serialize, Deserialize)]
struct UsesStringPair {
// Other fields ...
#[serde(with = "stringpair_serde")]
pub stringpair: StringPair,
}
fn main() {
let usp = UsesStringPair {
stringpair: StringPair("foo".to_string(), "bar".to_string()),
};
assert_eq!(
serde_json::json!(&usp).to_string(),
r#"{"stringpair":"foo:bar"}"#
);
let usp: UsesStringPair = serde_json::from_str(r#"{"stringpair":"baz:qux"}"#).unwrap();
assert_eq!(
usp.stringpair,
StringPair("baz".to_string(), "qux".to_string())
)
}
测试UsesStringPair
的派生序列化很容易进行简单的断言。但是我也看过serde_test
示例,因为那对我来说也有意义。
然而,我希望能够独立测试stringpair_serde::{serialize, deserialize}
函数(例如,如果我的crate只提供mycrate::StringPair
和mycrate::stringpair_serde
,而UsesStringPair
是供crate用户实现的)。
我研究了一种方法,就是创建一个serde_json::Serializer
(使用new
,需要一个io::Write
实现,我无法轻松地创建和使用它,但这是一个单独的问题),然后使用创建的Serializer调用serialize,在结果上进行断言,就像以前一样。然而,这并没有测试serde::Serializer
的任何/所有实现,只是在serde_json
中提供的一个实现。
我想知道是否有一种像serde_test
示例中适用于由模块提供的ser/deser函数的方法。
StringPair
派生这两个特征呢? - Ruifeng Xie&mut Vec<u8>
实现了io::Write
。 - user4815162342chrono::DateTime<Tz>
。它可以被序列化为字符串、Unix 时间戳、带有更高分辨率的整数时间戳(例如毫秒等)。因此,该类型本身实现了 Serialize、Deserialize 特性,但 chrono 还提供了子模块,可用于使用with = ...
以不同的方式序列化DateTime
值。 - Zia Ur RehmanStringPair
,并且它确实实现了ser/de特征,但模块编写者还希望为该类型的单调容器提供ser/de,例如Option<StringPair>
与StringPair
的序列化方式不同。有许多原因需要一个独立的ser/de模块而不是类型实现特征。 - Zia Ur Rehman