rust - 如何使用Serde的SeqDeserializer将序列反序列化为自定义类型?

标签 rust serde serde-json

我正在尝试为不复杂但没有自然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的文档不是那么容易理解,我无法在Visitor和如何从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)
    }
}

关于rust - 如何使用Serde的SeqDeserializer将序列反序列化为自定义类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62610076/

相关文章:

rust - 无法为生命周期参数克隆特征对象推断适当的生命周期

rust - 通过函数参数传入并使用Type?

json - 紫回调不同的Json结构

rust - 使用 serde 将枚举变量的名称作为字符串获取

rust - 函数参数中的可变借用

rust - 为什么不能在同一结构中存储值和对该值的引用?

json - 是否可以使用 json 的 json_serde::from_str() 获取值,其中字符串周围没有“”?

rust - 将对象转换为 serde_json::Value 无需序列化和反序列化

json - 如何将所有字段都是默认值的类型反序列化为 None ?