use alloc::collections::BTreeMap;
use core::fmt::{Formatter, Result as FmtResult};
use core::marker::PhantomData;
use serde::de::{Deserialize, Deserializer, Error, MapAccess, Visitor};
pub(crate) fn deserialize<'de, D, K, V>(deserializer: D) -> Result<BTreeMap<K, V>, D::Error>
where
D: Deserializer<'de>,
K: Deserialize<'de> + Ord,
V: Deserialize<'de>,
{
deserializer.deserialize_map(UniqueMap(PhantomData))
}
struct UniqueMap<K, V>(PhantomData<(K, V)>);
impl<'de, K, V> Visitor<'de> for UniqueMap<K, V>
where
K: Deserialize<'de> + Ord,
V: Deserialize<'de>,
{
type Value = BTreeMap<K, V>;
fn expecting(&self, f: &mut Formatter<'_>) -> FmtResult {
f.write_str("a map in which each name appears once")
}
fn visit_map<M: MapAccess<'de>>(self, mut map: M) -> Result<Self::Value, M::Error> {
let mut entries = BTreeMap::new();
while let Some((key, value)) = map.next_entry()? {
if entries.contains_key(&key) {
return Err(M::Error::custom("a name appears twice in the map"));
}
entries.insert(key, value);
}
Ok(entries)
}
}