use std::collections::BTreeSet;
use std::collections::BTreeMap;
use serde::Serializer;
use serde::Deserializer;
use serde::ser::SerializeMap;
use serde::de::MapAccess;
use serde::de::Visitor;
use uuid::Uuid;
use std::fmt;
pub fn serialize<S>(
map: &BTreeMap<BTreeSet<String>, Uuid>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut ser_map = serializer.serialize_map(Some(map.len()))?;
for (k, v) in map {
let key_str = k.iter().cloned().collect::<Vec<_>>().join("|");
ser_map.serialize_entry(&key_str, v)?;
}
ser_map.end()
}
pub fn deserialize<'de, D>(
deserializer: D,
) -> Result<BTreeMap<BTreeSet<String>, Uuid>, D::Error>
where
D: Deserializer<'de>,
{
struct MapVisitor;
impl<'de> Visitor<'de> for MapVisitor {
type Value = BTreeMap<BTreeSet<String>, Uuid>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a map with pipe-separated string keys")
}
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let mut map = BTreeMap::new();
while let Some((key_str, value)) = access.next_entry::<String, Uuid>()? {
let key_set = key_str.split('|').map(|s| s.to_string()).collect::<BTreeSet<_>>();
map.insert(key_set, value);
}
Ok(map)
}
}
deserializer.deserialize_map(MapVisitor)
}