use std::collections::BTreeSet;
use serde::{
de::DeserializeOwned, ser::SerializeSeq, Deserialize, Deserializer, Serialize,
Serializer,
};
use crate::openapi::serde_helpers::deserialize_enum_helper;
use super::ref_or::ExpectedWhenParsing;
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<BTreeSet<T>, D::Error>
where
T: DeserializeOwned + Eq + Ord + ExpectedWhenParsing,
D: Deserializer<'de>,
{
let mut set = BTreeSet::new();
match VecOrScalar::deserialize(deserializer)? {
VecOrScalar::<T>::Vec(v) => {
for s in v {
set.insert(s);
}
}
VecOrScalar::<T>::Scalar(s) => {
set.insert(s);
}
}
Ok(set)
}
pub fn serialize<T, S>(set: &BTreeSet<T>, serializer: S) -> Result<S::Ok, S::Error>
where
T: Eq + Ord + Serialize,
S: Serializer,
{
if set.len() == 1 {
let s = set.iter().next().expect("did not contain element");
s.serialize(serializer)
} else {
let mut seq_serializer = serializer.serialize_seq(Some(set.len()))?;
for s in set {
seq_serializer.serialize_element(s)?;
}
seq_serializer.end()
}
}
enum VecOrScalar<T: DeserializeOwned> {
Vec(Vec<T>),
Scalar(T),
}
impl<'de, T: ExpectedWhenParsing + DeserializeOwned> Deserialize<'de>
for VecOrScalar<T>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
use serde_yaml::Value;
let yaml = Value::deserialize(deserializer)?;
if yaml.is_sequence() {
Ok(VecOrScalar::Vec(deserialize_enum_helper::<D, _>(
&format!(
"array of {}",
<T as ExpectedWhenParsing>::expected_when_parsing(),
),
yaml,
)?))
} else {
Ok(VecOrScalar::Scalar(deserialize_enum_helper::<D, _>(
<T as ExpectedWhenParsing>::expected_when_parsing(),
yaml,
)?))
}
}
}