use std::collections::BTreeSet;
use serde::Serialize;
pub fn sorted_serialize<S, T, L>(list: L, s: S) -> Result<S::Ok, S::Error>
where
L: IntoIterator<Item = T>,
S: serde::Serializer,
T: Ord + Serialize + Clone,
{
let ordered_list: BTreeSet<T> = list.into_iter().collect();
Serialize::serialize(&ordered_list, s)
}
#[cfg(test)]
mod tests {
#![allow(non_snake_case)]
use serde_derive::{Deserialize, Serialize};
use std::collections::HashSet;
#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
struct SampleData {
#[serde(serialize_with = "super::sorted_serialize")]
values: HashSet<String>,
}
#[test]
fn serde_roundtrip__produces_matching_data() {
let data = SampleData {
values: {
let mut set = HashSet::new();
set.insert("foo".into());
set.insert("abc".into());
set.insert("123".into());
set
},
};
let string = serde_yaml::to_string(&data).unwrap();
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 {
let data = SampleData {
values: {
let mut set = HashSet::new();
set.insert("d".into());
set.insert("a".into());
set.insert("e".into());
set.insert("c".into());
set.insert("b".into());
set
},
};
let string = serde_yaml::to_string(&data).unwrap();
assert_eq!(
string,
r###"---
values:
- a
- b
- c
- d
- e
"###
);
}
}
}