如何使用 Serde 的 SeqDeserializer 将序列反序列化为自定义类型?
How to deserialize a sequence into a custom type with Serde's SeqDeserializer?
我正在尝试为不复杂但没有自然 JSON 表示的类型编写自定义序列化程序和反序列化程序。
pub type ArrayKey = [i16; 5];
pub struct ArrayKeyedMap {
the_map: HashMap<ArrayKey, u32>
}
具有数组键的 HashMap 不能表示为 JSON 映射(必须具有字符串键)。所以我想将它序列化为一对序列。 Serialization of a sequence 的文档非常清楚,下面的工作:
impl Serialize for ArrayKeyedMap {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.the_map.len()))?;
for (the_key, the_val) in self.the_map.iter() {
seq.serialize_element(the_key)?;
seq.serialize_element(the_val)?;
}
seq.end()
}
}
这序列化为例如[[1,2,3,4,5], 1, [5,4,3,2,1], 2]
。 deserialization of a sequence 的文档不太容易理解,我无法在访问者和如何从 SeqDeserializer
检索数据之间进行跳跃。我不确定我是要传入某些内容,还是要获取返回值,或者其他内容。
impl<'de> Deserialize<'de> for ArrayKeyedMap
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(SeqDeserializer::new // not sure how to proceed
}
}
如何使用数组键将其反序列化回地图?
不确定这是否是完美的答案,但这是有效的。 Visitor 需要作为一个单独的结构体来实现,这比序列化器稍微复杂一些。但是文档对此发出警告!
impl ArrayKeyedMap {
pub fn new() -> ArrayKeyedMap {
ArrayKeyedMap {
the_map: HashMap::new(),
}
}
}
impl Serialize for ArrayKeyedMap {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.the_map.len()))?;
for (the_key, the_val) in self.the_map.iter() {
seq.serialize_element(the_key)?;
seq.serialize_element(the_val)?;
}
seq.end()
}
}
struct ArrayKeyedMapDeserializer;
impl<'de> Visitor<'de> for ArrayKeyedMapDeserializer {
type Value = ArrayKeyedMap;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("ArrayKeyedMap key value sequence.")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut new_obj = ArrayKeyedMap::new();
while let Some(key) = seq.next_element()? {
if let Some(value) = seq.next_element()? {
new_obj.the_map.insert(key, value);
} else {
return Err(de::Error::custom(format!(
"Didn't find the right sequence of values in ArrayKeyedMap."
)));
}
}
Ok(new_obj)
}
}
impl<'de> Deserialize<'de> for ArrayKeyedMap {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ArrayKeyedMapDeserializer)
}
}
我正在尝试为不复杂但没有自然 JSON 表示的类型编写自定义序列化程序和反序列化程序。
pub type ArrayKey = [i16; 5];
pub struct ArrayKeyedMap {
the_map: HashMap<ArrayKey, u32>
}
具有数组键的 HashMap 不能表示为 JSON 映射(必须具有字符串键)。所以我想将它序列化为一对序列。 Serialization of a sequence 的文档非常清楚,下面的工作:
impl Serialize for ArrayKeyedMap {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.the_map.len()))?;
for (the_key, the_val) in self.the_map.iter() {
seq.serialize_element(the_key)?;
seq.serialize_element(the_val)?;
}
seq.end()
}
}
这序列化为例如[[1,2,3,4,5], 1, [5,4,3,2,1], 2]
。 deserialization of a sequence 的文档不太容易理解,我无法在访问者和如何从 SeqDeserializer
检索数据之间进行跳跃。我不确定我是要传入某些内容,还是要获取返回值,或者其他内容。
impl<'de> Deserialize<'de> for ArrayKeyedMap
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(SeqDeserializer::new // not sure how to proceed
}
}
如何使用数组键将其反序列化回地图?
不确定这是否是完美的答案,但这是有效的。 Visitor 需要作为一个单独的结构体来实现,这比序列化器稍微复杂一些。但是文档对此发出警告!
impl ArrayKeyedMap {
pub fn new() -> ArrayKeyedMap {
ArrayKeyedMap {
the_map: HashMap::new(),
}
}
}
impl Serialize for ArrayKeyedMap {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut seq = serializer.serialize_seq(Some(self.the_map.len()))?;
for (the_key, the_val) in self.the_map.iter() {
seq.serialize_element(the_key)?;
seq.serialize_element(the_val)?;
}
seq.end()
}
}
struct ArrayKeyedMapDeserializer;
impl<'de> Visitor<'de> for ArrayKeyedMapDeserializer {
type Value = ArrayKeyedMap;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("ArrayKeyedMap key value sequence.")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut new_obj = ArrayKeyedMap::new();
while let Some(key) = seq.next_element()? {
if let Some(value) = seq.next_element()? {
new_obj.the_map.insert(key, value);
} else {
return Err(de::Error::custom(format!(
"Didn't find the right sequence of values in ArrayKeyedMap."
)));
}
}
Ok(new_obj)
}
}
impl<'de> Deserialize<'de> for ArrayKeyedMap {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_seq(ArrayKeyedMapDeserializer)
}
}