use std::cmp::Ordering;
use indexmap::IndexMap;
use serde::Serialize;
use crate::Value;
#[derive(Default, Debug)]
pub struct Outputs {
name: Option<String>,
values: IndexMap<String, Value>,
}
impl Outputs {
pub fn with_name(mut self, name: impl Into<String>) -> Self {
self.name = Some(name.into());
self
}
pub fn iter(&self) -> impl Iterator<Item = (&str, &Value)> + use<'_> {
self.values.iter().map(|(k, v)| (k.as_str(), v))
}
pub fn get(&self, name: &str) -> Option<&Value> {
self.values.get(name)
}
pub(crate) fn sort_by(&mut self, mut cmp: impl FnMut(&str, &str) -> Ordering) {
self.values.sort_unstable_by(move |a, _, b, _| {
let ordering = cmp(a, b);
assert!(ordering != Ordering::Equal);
ordering
});
}
}
impl Serialize for Outputs {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeMap;
let mut s = serializer.serialize_map(Some(self.values.len()))?;
for (k, v) in &self.values {
let v = crate::ValueSerializer::new(None, v, true);
match &self.name {
Some(prefix) => s.serialize_entry(&format!("{prefix}.{k}"), &v)?,
None => s.serialize_entry(k, &v)?,
}
}
s.end()
}
}
impl FromIterator<(String, Value)> for Outputs {
fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
Self {
name: None,
values: iter.into_iter().collect(),
}
}
}
impl From<IndexMap<String, Value>> for Outputs {
fn from(values: IndexMap<String, Value>) -> Self {
Self { name: None, values }
}
}