diff --git a/ruma-serde/src/strings.rs b/ruma-serde/src/strings.rs index 53f3728a..68ccb814 100644 --- a/ruma-serde/src/strings.rs +++ b/ruma-serde/src/strings.rs @@ -1,8 +1,8 @@ -use std::{collections::BTreeMap, convert::TryInto, fmt}; +use std::{collections::BTreeMap, convert::TryInto, fmt, marker::PhantomData}; use js_int::Int; use serde::{ - de::{self, Deserializer, IntoDeserializer as _, Visitor}, + de::{self, Deserializer, IntoDeserializer as _, MapAccess, Visitor}, Deserialize, }; @@ -117,7 +117,38 @@ where } } - Ok(BTreeMap::::deserialize(de)?.into_iter().map(|(k, IntWrap(v))| (k, v)).collect()) + struct IntMapVisitor { + _phantom: PhantomData, + } + + impl IntMapVisitor { + fn new() -> Self { + Self { _phantom: PhantomData } + } + } + + impl<'de, T> Visitor<'de> for IntMapVisitor + where + T: Deserialize<'de> + Ord, + { + type Value = BTreeMap; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map with integers or stings as values") + } + + fn visit_map>(self, mut map: A) -> Result { + let mut res = BTreeMap::new(); + + while let Some((k, IntWrap(v))) = map.next_entry()? { + res.insert(k, v); + } + + Ok(res) + } + } + + de.deserialize_map(IntMapVisitor::new()) } #[cfg(test)]