//! Serialize a HashMap of ID-keyed structs that also contain the ID inside //! to a plain list, and also back when deserializing. use std::collections::HashMap; use crate::ID; use serde::{Serialize, Deserializer, Deserialize, de}; use serde::ser::SerializeSeq; use serde::de::{Visitor, SeqAccess, Unexpected}; use std::fmt; use crate::id::HaveId; use std::marker::PhantomData; pub fn serialize(x: &HashMap, s: S) -> Result where S: serde::Serializer, X: Serialize + HaveId { let mut seq = s.serialize_seq(Some(x.len()))?; for p in x.values() { seq.serialize_element(p)?; } seq.end() } pub fn deserialize<'de, D, X>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, X: Deserialize<'de> + HaveId { deserializer.deserialize_seq(SeqToMap(Default::default())) } pub struct SeqToMap(PhantomData); impl<'de, X : Deserialize<'de> + HaveId> Visitor<'de> for SeqToMap { type Value = HashMap; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("sequence of items with id") } fn visit_seq(self, mut seq: A) -> Result where A: SeqAccess<'de>, { let mut map = HashMap::::new(); while let Some(next) = seq.next_element::()? { map.insert(next.get_id(), next); } Ok(map) } }