#ordered #serde #serialization #sorting #map #hash-map

serde-ordered-collections

Ordered serialization/deserialization serde functionality

1 stable release

2.0.0 Feb 21, 2023

#2108 in Data structures

MIT/Apache

8KB
142 lines

serde-ordered-collections

A serialization function, intended for use with serde_derive's serialize_with annotation, which sorts the entries in a map- or list-like structure during serialization according to the key's Ord implementation.

This library supports anything implementing IntoIterator<Item = (K, V)> for K: Ord, or IntoIterator<Item = V> for V: Ord. Examples include std::collections::HashMap and std::collections::HashSet, respectively.

In addition to producing a sorted list, which may be convenient for human consumption, this also ensures that the serialized output is deterministic. HashMap/HashSet, by default, will be ordered non-deterministically due to its implicit random seeding; this makes it inappropriate when consistent output matters.

Usage

Add the following annotation to your HashMap (or other map-like) field:

#[serde(serialize_with = "serde_ordered_collections::map::sorted_serialize")]

Or the equivalent for a HashSet (or list-like):

#[serde(serialize_with = "serde_ordered_collections::flat::sorted_serialize")]

If you were previously serializing a plain HashMap rather than a custom type, the easiest way to use this helper is to wrap your HashMap in a new single-field struct and then apply flatten as follows:

#[serde(flatten, serialize_with = "serde_ordered_collections::map::sorted_serialize")]

Complete example using HashMap

use std::collections::HashMap;
use serde_derive::{Deserialize, Serialize};

#[derive(Debug, Serialize)]
struct SampleData {
    #[serde(serialize_with = "serde_ordered_collections::map::sorted_serialize")]
    values: HashMap<String, String>,
}

let sample_instance = SampleData {
    values: {
        let mut map = HashMap::new();
        map.insert("c".into(), "ghi".into());
        map.insert("a".into(), "abc".into());
        map.insert("b".into(), "def".into());

        map
    },
};

let serialized_string = serde_yaml::to_string(&sample_instance).unwrap();
assert_eq!(&serialized_string, "\
---
values:
  a: abc
  b: def
  c: ghi
");

Dependencies

~110–345KB