pub mod map_as_vec {
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use serde::de::Deserializer;
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
pub fn serialize<S, K, V, H>(map: &HashMap<K, V, H>, serializer: S) -> Result<S::Ok, S::Error>
where
K: Serialize + Eq + Hash + Ord,
V: Serialize,
S: Serializer,
{
let mut pairs: Vec<(&K, &V)> = map.iter().collect();
pairs.sort_unstable_by(|a, b| a.0.cmp(b.0));
pairs.serialize(serializer)
}
pub fn deserialize<'de, D, K, V, H>(deserializer: D) -> Result<HashMap<K, V, H>, D::Error>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
D: Deserializer<'de>,
H: BuildHasher + Default,
{
let pairs: Vec<(K, V)> = Vec::deserialize(deserializer)?;
Ok(pairs.into_iter().collect())
}
}
pub mod map_as_vec_default {
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use serde::de::Deserializer;
use serde::ser::Serializer;
use serde::{Deserialize, Serialize};
pub fn serialize<S, K, V, H>(map: &HashMap<K, V, H>, serializer: S) -> Result<S::Ok, S::Error>
where
K: Serialize + Eq + Hash + Ord,
V: Serialize,
S: Serializer,
{
let mut pairs: Vec<(&K, &V)> = map.iter().collect();
pairs.sort_unstable_by(|a, b| a.0.cmp(b.0));
pairs.serialize(serializer)
}
pub fn deserialize<'de, D, K, V, H>(deserializer: D) -> Result<HashMap<K, V, H>, D::Error>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
D: Deserializer<'de>,
H: BuildHasher + Default,
{
let pairs: Vec<(K, V)> = Vec::deserialize(deserializer)?;
Ok(pairs.into_iter().collect())
}
}
pub mod sorted_map {
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use serde::de::Deserializer;
use serde::ser::{SerializeMap as _, Serializer};
use serde::{Deserialize, Serialize};
pub fn serialize<S, K, V, H>(map: &HashMap<K, V, H>, serializer: S) -> Result<S::Ok, S::Error>
where
K: Serialize + Eq + Hash + Ord,
V: Serialize,
S: Serializer,
{
let mut pairs: Vec<(&K, &V)> = map.iter().collect();
pairs.sort_unstable_by(|a, b| a.0.cmp(b.0));
let mut entries = serializer.serialize_map(Some(pairs.len()))?;
for (key, value) in pairs {
entries.serialize_entry(key, value)?;
}
entries.end()
}
pub fn deserialize<'de, D, K, V, H>(deserializer: D) -> Result<HashMap<K, V, H>, D::Error>
where
K: Deserialize<'de> + Eq + Hash,
V: Deserialize<'de>,
D: Deserializer<'de>,
H: BuildHasher + Default,
{
HashMap::deserialize(deserializer)
}
}
pub mod sorted_nested_map {
use std::collections::HashMap;
use std::hash::{BuildHasher, Hash};
use serde::de::Deserializer;
use serde::ser::{SerializeMap as _, Serializer};
use serde::{Deserialize, Serialize};
type Nested<K, IK, IV, H, IH> = HashMap<K, HashMap<IK, IV, IH>, H>;
struct Inner<'a, K, V, H>(&'a HashMap<K, V, H>);
impl<K, V, H> Serialize for Inner<'_, K, V, H>
where
K: Serialize + Eq + Hash + Ord,
V: Serialize,
{
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
super::sorted_map::serialize(self.0, serializer)
}
}
pub fn serialize<S, K, IK, IV, H, IH>(
map: &Nested<K, IK, IV, H, IH>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
K: Serialize + Eq + Hash + Ord,
IK: Serialize + Eq + Hash + Ord,
IV: Serialize,
S: Serializer,
{
let mut pairs: Vec<(&K, &HashMap<IK, IV, IH>)> = map.iter().collect();
pairs.sort_unstable_by(|a, b| a.0.cmp(b.0));
let mut entries = serializer.serialize_map(Some(pairs.len()))?;
for (key, inner) in pairs {
entries.serialize_entry(key, &Inner(inner))?;
}
entries.end()
}
pub fn deserialize<'de, D, K, IK, IV, H, IH>(
deserializer: D,
) -> Result<Nested<K, IK, IV, H, IH>, D::Error>
where
K: Deserialize<'de> + Eq + Hash,
IK: Deserialize<'de> + Eq + Hash,
IV: Deserialize<'de>,
D: Deserializer<'de>,
H: BuildHasher + Default,
IH: BuildHasher + Default,
{
HashMap::deserialize(deserializer)
}
}
pub mod sorted_set {
use std::collections::HashSet;
use std::hash::{BuildHasher, Hash};
use serde::de::Deserializer;
use serde::ser::{SerializeSeq as _, Serializer};
use serde::{Deserialize, Serialize};
pub fn serialize<S, T, H>(set: &HashSet<T, H>, serializer: S) -> Result<S::Ok, S::Error>
where
T: Serialize + Eq + Hash + Ord,
S: Serializer,
{
let mut members: Vec<&T> = set.iter().collect();
members.sort_unstable();
let mut seq = serializer.serialize_seq(Some(members.len()))?;
for member in members {
seq.serialize_element(member)?;
}
seq.end()
}
pub fn deserialize<'de, D, T, H>(deserializer: D) -> Result<HashSet<T, H>, D::Error>
where
T: Deserialize<'de> + Eq + Hash,
D: Deserializer<'de>,
H: BuildHasher + Default,
{
HashSet::deserialize(deserializer)
}
}
#[cfg(test)]
#[allow(clippy::unwrap_used)]
mod tests {
use std::collections::HashMap;
use crate::Edge;
#[test]
fn schema_with_edges_json_roundtrip() {
let mut schema = crate::Schema {
protocol: "test".into(),
vertices: HashMap::from([
(
"root".into(),
crate::Vertex {
id: "root".into(),
kind: "object".into(),
nsid: None,
},
),
(
"root.name".into(),
crate::Vertex {
id: "root.name".into(),
kind: "string".into(),
nsid: None,
},
),
]),
edges: HashMap::new(),
hyper_edges: HashMap::new(),
constraints: HashMap::new(),
required: HashMap::new(),
nsids: HashMap::new(),
entries: Vec::new(),
variants: HashMap::new(),
orderings: HashMap::new(),
recursion_points: HashMap::new(),
spans: HashMap::new(),
usage_modes: HashMap::new(),
nominal: HashMap::new(),
coercions: HashMap::new(),
mergers: HashMap::new(),
defaults: HashMap::new(),
policies: HashMap::new(),
outgoing: HashMap::new(),
incoming: HashMap::new(),
between: HashMap::new(),
};
let edge = Edge {
src: "root".into(),
tgt: "root.name".into(),
kind: "prop".into(),
name: Some("name".into()),
};
schema.edges.insert(edge, "prop".into());
let json = serde_json::to_string_pretty(&schema).unwrap();
let recovered: crate::Schema = serde_json::from_str(&json).unwrap();
assert_eq!(schema.edges.len(), recovered.edges.len());
assert_eq!(schema.vertices.len(), recovered.vertices.len());
}
#[test]
fn schema_with_edges_msgpack_roundtrip() {
let mut schema = crate::Schema {
protocol: "test".into(),
vertices: HashMap::new(),
edges: HashMap::new(),
hyper_edges: HashMap::new(),
constraints: HashMap::new(),
required: HashMap::new(),
nsids: HashMap::new(),
entries: Vec::new(),
variants: HashMap::new(),
orderings: HashMap::new(),
recursion_points: HashMap::new(),
spans: HashMap::new(),
usage_modes: HashMap::new(),
nominal: HashMap::new(),
coercions: HashMap::new(),
mergers: HashMap::new(),
defaults: HashMap::new(),
policies: HashMap::new(),
outgoing: HashMap::new(),
incoming: HashMap::new(),
between: HashMap::new(),
};
let edge = Edge {
src: "a".into(),
tgt: "b".into(),
kind: "prop".into(),
name: None,
};
schema.edges.insert(edge, "prop".into());
let bytes = rmp_serde::to_vec(&schema).unwrap();
let recovered: crate::Schema = rmp_serde::from_slice(&bytes).unwrap();
assert_eq!(schema.edges.len(), recovered.edges.len());
}
}