use std::collections::HashMap;
use serde::{Serialize, Serializer};
use serde::ser::SerializeSeq;
#[derive(Clone, Debug, Default)]
pub struct ListContainersRequest {
pub all: Option<bool>,
pub limit: Option<usize>,
pub size: Option<bool>,
pub filters: Filters,
}
impl ListContainersRequest {
pub fn all(mut self, v: bool) -> Self {
self.all = Some(v);
self
}
pub fn limit(mut self, v: usize) -> Self {
self.limit = Some(v);
self
}
pub fn size(mut self, v: bool) -> Self {
self.size = Some(v);
self
}
pub fn filters(mut self, v: Filters) -> Self {
self.filters = v;
self
}
}
#[derive(Clone, Default, Debug, Serialize)]
pub struct Filters {
#[serde(rename = "label", serialize_with = "sz_labels")]
labels: HashMap<String, Option<String>>
}
impl Filters {
pub(crate) fn is_empty(&self) -> bool {
self.labels.is_empty()
}
pub fn label_present<K: Into<String>>(mut self, k: K) -> Self {
self.labels.insert(k.into(), None);
self
}
pub fn label_value<K: Into<String>, V: Into<String>>(mut self, k: K, v: V) -> Self {
self.labels.insert(k.into(), Some(v.into()));
self
}
}
fn sz_labels<SZ>(labels: &HashMap<String, Option<String>>, serializer: SZ) -> Result<SZ::Ok, SZ::Error>
where SZ: Serializer
{
let mut sequence_sz = serializer.serialize_seq(Some(labels.len()))?;
for (k, ov) in labels {
match ov {
Some(v) => {
sequence_sz.serialize_element(&format!("{}={}", k, v))?;
},
None => {
sequence_sz.serialize_element(k)?;
}
}
}
sequence_sz.end()
}
#[cfg(test)]
pub mod test_serialize_filters {
use super::Filters;
#[test]
pub fn empty() {
let filters = Filters::default();
assert!(filters.is_empty());
}
#[test]
pub fn label_only() {
let filters = Filters::default()
.label_present("foo");
let actual = serde_json::to_string(&filters)
.unwrap();
assert_eq!("{\"label\":[\"foo\"]}".to_string(), actual);
}
#[test]
pub fn label_with_value() {
let filters = Filters::default()
.label_value("foo", "bar");
let actual = serde_json::to_string(&filters)
.unwrap();
assert_eq!("{\"label\":[\"foo=bar\"]}".to_string(), actual);
}
}