1use std::cmp::Ordering;
4
5use indexmap::IndexMap;
6use serde::Serialize;
7
8use crate::Value;
9
10#[derive(Default, Debug)]
12pub struct Outputs {
13 name: Option<String>,
18 values: IndexMap<String, Value>,
20}
21
22impl Outputs {
23 pub fn with_name(mut self, name: impl Into<String>) -> Self {
27 self.name = Some(name.into());
28 self
29 }
30
31 pub fn iter(&self) -> impl Iterator<Item = (&str, &Value)> + use<'_> {
33 self.values.iter().map(|(k, v)| (k.as_str(), v))
34 }
35
36 pub fn get(&self, name: &str) -> Option<&Value> {
40 self.values.get(name)
41 }
42
43 pub(crate) fn sort_by(&mut self, mut cmp: impl FnMut(&str, &str) -> Ordering) {
45 self.values.sort_unstable_by(move |a, _, b, _| {
48 let ordering = cmp(a, b);
49 assert!(ordering != Ordering::Equal);
50 ordering
51 });
52 }
53}
54
55impl Serialize for Outputs {
56 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
57 where
58 S: serde::Serializer,
59 {
60 use serde::ser::SerializeMap;
61
62 let mut s = serializer.serialize_map(Some(self.values.len()))?;
63 for (k, v) in &self.values {
64 let v = crate::ValueSerializer::new(None, v, true);
65 match &self.name {
66 Some(prefix) => s.serialize_entry(&format!("{prefix}.{k}"), &v)?,
67 None => s.serialize_entry(k, &v)?,
68 }
69 }
70
71 s.end()
72 }
73}
74
75impl FromIterator<(String, Value)> for Outputs {
76 fn from_iter<T: IntoIterator<Item = (String, Value)>>(iter: T) -> Self {
77 Self {
78 name: None,
79 values: iter.into_iter().collect(),
80 }
81 }
82}
83
84impl From<IndexMap<String, Value>> for Outputs {
85 fn from(values: IndexMap<String, Value>) -> Self {
86 Self { name: None, values }
87 }
88}