summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJonas Pommerening <jonas.pommerening@gmail.com>2021-04-01 12:04:26 +0200
committerJonas Pommerening <jonas.pommerening@gmail.com>2021-04-12 15:57:00 +0200
commitcb80052e8e3a65e01063ccc17f7350aab032bc09 (patch)
tree0bec9983f73889c7e54e2eafdbbdc46da9c97360 /src
parent9750d29614776e1372ef8b6580e0ae0eedc6801f (diff)
Allow multiple filters of same type and fix ExitCode filter name
Diffstat (limited to 'src')
-rw-r--r--src/container.rs81
1 files changed, 75 insertions, 6 deletions
diff --git a/src/container.rs b/src/container.rs
index 24c41d6..2b3ee84 100644
--- a/src/container.rs
+++ b/src/container.rs
@@ -504,14 +504,19 @@ impl ContainerListOptionsBuilder {
&mut self,
filters: Vec<ContainerFilter>,
) -> &mut Self {
- let mut param = HashMap::new();
+ let mut param: HashMap<&str, Vec<String>> = HashMap::new();
for f in filters {
- match f {
- ContainerFilter::ExitCode(c) => param.insert("exit", vec![c.to_string()]),
- ContainerFilter::Status(s) => param.insert("status", vec![s]),
- ContainerFilter::LabelName(n) => param.insert("label", vec![n]),
- ContainerFilter::Label(n, v) => param.insert("label", vec![format!("{}={}", n, v)]),
+ let (key, value) = match f {
+ ContainerFilter::ExitCode(c) => ("exited", c.to_string()),
+ ContainerFilter::Status(s) => ("status", s),
+ ContainerFilter::LabelName(n) => ("label", n),
+ ContainerFilter::Label(n, v) => ("label", format!("{}={}", n, v)),
};
+ if let Some(values) = param.get_mut(key) {
+ values.push(value);
+ } else {
+ param.insert(key, vec![value]);
+ }
}
// structure is a a json encoded object mapping string keys to a list
// of string values
@@ -1409,6 +1414,7 @@ pub struct Exit {
#[cfg(test)]
mod tests {
use super::*;
+ use crate::container::ContainerFilter::{ExitCode, Label, LabelName, Status};
#[test]
fn container_options_simple() {
@@ -1562,6 +1568,69 @@ mod tests {
);
}
+ #[test]
+ fn container_list_options_multiple_labels() {
+ let options = ContainerListOptions::builder()
+ .filter(vec![
+ Label("label1".to_string(), "value".to_string()),
+ LabelName("label2".to_string()),
+ ])
+ .build();
+
+ let form = form_urlencoded::Serializer::new(String::new())
+ .append_pair("filters", r#"{"label":["label1=value","label2"]}"#)
+ .finish();
+
+ assert_eq!(form, options.serialize().unwrap())
+ }
+
+ #[test]
+ fn container_list_options_exit_code() {
+ let options = ContainerListOptions::builder()
+ .filter(vec![ExitCode(0)])
+ .build();
+
+ let form = form_urlencoded::Serializer::new(String::new())
+ .append_pair("filters", r#"{"exited":["0"]}"#)
+ .finish();
+
+ assert_eq!(form, options.serialize().unwrap())
+ }
+
+ #[test]
+ fn container_list_options_status() {
+ let options = ContainerListOptions::builder()
+ .filter(vec![Status("running".to_string())])
+ .build();
+
+ let form = form_urlencoded::Serializer::new(String::new())
+ .append_pair("filters", r#"{"status":["running"]}"#)
+ .finish();
+
+ assert_eq!(form, options.serialize().unwrap())
+ }
+
+ #[test]
+ fn container_list_options_combined() {
+ let options = ContainerListOptions::builder()
+ .all()
+ .filter(vec![
+ Label("label1".to_string(), "value".to_string()),
+ LabelName("label2".to_string()),
+ ExitCode(0),
+ Status("running".to_string()),
+ ])
+ .build();
+
+ let serialized = options.serialize().unwrap();
+
+ assert!(serialized.contains("all=true"));
+ assert!(serialized.contains("filters="));
+ assert!(serialized.contains("%22label%22%3A%5B%22label1%3Dvalue%22%2C%22label2%22%5D"));
+ assert!(serialized.contains("%22status%22%3A%5B%22running%22%5D"));
+ assert!(serialized.contains("%22exited%22%3A%5B%220%22%5D"));
+ }
+
#[cfg(feature = "chrono")]
#[test]
fn logs_options() {