serde-ordered-collections 2.0.0

Ordered serialization/deserialization serde functionality
Documentation
use serde::Serialize;
use std::collections::BTreeMap;

pub fn sorted_serialize<S, K, V, M>(map: M, s: S) -> Result<S::Ok, S::Error>
where
    M: IntoIterator<Item = (K, V)>,
    S: serde::Serializer,
    K: Ord + Serialize + Clone,
    V: Serialize + Clone,
{
    let ordered_map: BTreeMap<K, V> = map.into_iter().collect();
    Serialize::serialize(&ordered_map, s)
}

#[cfg(test)]
mod tests {
    #![allow(non_snake_case)]

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

    #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
    struct SampleData {
        #[serde(flatten, serialize_with = "super::sorted_serialize")]
        values: HashMap<String, String>,
    }

    #[test]
    fn serde_roundtrip__produces_matching_data() {
        // Given
        let data = SampleData {
            values: {
                let mut map = HashMap::new();
                map.insert("foo".into(), "bar".into());
                map.insert("abc".into(), "def".into());
                map.insert("123".into(), "456".into());

                map
            },
        };

        // When
        let string = serde_yaml::to_string(&data).unwrap();

        // Then
        let deserialized_data: SampleData = serde_yaml::from_str(&string).unwrap();
        assert_eq!(data, deserialized_data);
    }

    #[test]
    fn yaml_to_string__produces_correctly_sorted_order_consistently() {
        for _i in 0..100 {
            // Given
            let data = SampleData {
                values: {
                    let mut map = HashMap::new();
                    map.insert("d".into(), "jkl".into());
                    map.insert("a".into(), "abc".into());
                    map.insert("e".into(), "mno".into());
                    map.insert("c".into(), "ghi".into());
                    map.insert("b".into(), "def".into());

                    map
                },
            };

            // When
            let string = serde_yaml::to_string(&data).unwrap();

            // Then
            assert_eq!(
                string,
                r###"---
a: abc
b: def
c: ghi
d: jkl
e: mno
"###
            );
        }
    }
}