You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
54 lines
1.4 KiB
54 lines
1.4 KiB
//! 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};
|
|
use serde::ser::SerializeSeq;
|
|
use serde::de::{Visitor, SeqAccess};
|
|
use std::fmt;
|
|
use crate::id::HaveId;
|
|
use std::marker::PhantomData;
|
|
|
|
pub fn serialize<S, X>(x: &HashMap<ID, X>, s: S) -> Result<S::Ok, S::Error>
|
|
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<HashMap<ID, X>, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
X: Deserialize<'de> + HaveId
|
|
{
|
|
deserializer.deserialize_seq(SeqToMap(Default::default()))
|
|
}
|
|
|
|
pub struct SeqToMap<X>(PhantomData<X>);
|
|
|
|
impl<'de, X : Deserialize<'de> + HaveId> Visitor<'de> for SeqToMap<X> {
|
|
type Value = HashMap<ID, X>;
|
|
|
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
formatter.write_str("sequence of items with id")
|
|
}
|
|
|
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
|
where
|
|
A: SeqAccess<'de>,
|
|
{
|
|
let mut map = HashMap::<ID, X>::new();
|
|
|
|
while let Some(next) = seq.next_element::<X>()? {
|
|
map.insert(next.get_id(), next);
|
|
}
|
|
|
|
Ok(map)
|
|
}
|
|
}
|
|
|