use std::fmt;
use std::marker::PhantomData;
use serde::de::{self, Deserializer, MapAccess, Visitor};
use serde::ser::{SerializeMap, Serializer};
use serde::{Deserialize, Serialize};
pub(crate) trait Keyed {
fn key(&self) -> &str;
fn set_key(&mut self, key: String);
}
pub(crate) fn deserialize<'de, D, T>(de: D) -> Result<Vec<T>, D::Error>
where
D: Deserializer<'de>,
T: Deserialize<'de> + Keyed,
{
struct KeyedVisitor<T>(PhantomData<T>);
impl<'de, T> Visitor<'de> for KeyedVisitor<T>
where
T: Deserialize<'de> + Keyed,
{
type Value = Vec<T>;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("a map of named entries")
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> Result<Self::Value, A::Error> {
let mut out = Vec::with_capacity(map.size_hint().unwrap_or(0));
while let Some(key) = map.next_key::<String>()? {
let mut value: T = map.next_value()?;
value.set_key(key);
out.push(value);
}
Ok(out)
}
fn visit_unit<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(Vec::new())
}
}
de.deserialize_map(KeyedVisitor(PhantomData))
}
pub(crate) fn serialize<S, T>(items: &[T], ser: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
T: Serialize + Keyed,
{
let mut map = ser.serialize_map(Some(items.len()))?;
for item in items {
map.serialize_entry(item.key(), item)?;
}
map.end()
}