stackify_docker_api/opts/
service.rs

1use crate::{models, opts::RegistryAuth, Error, Result};
2use containers_api::opts::{Filter, FilterItem};
3use containers_api::{impl_filter_func, impl_opts_builder, impl_url_bool_field};
4
5use std::collections::HashMap;
6use std::hash::Hash;
7
8use serde::Serialize;
9use serde_json::{json, Value};
10
11/// Filter Opts for services listings
12pub enum ServiceFilter {
13    Id(String),
14    Label(String),
15    ReplicatedMode,
16    GlobalMode,
17    Name(String),
18}
19
20impl Filter for ServiceFilter {
21    fn query_item(&self) -> FilterItem {
22        match &self {
23            ServiceFilter::Id(i) => FilterItem::new("id", i.to_owned()),
24            ServiceFilter::Label(l) => FilterItem::new("label", l.to_owned()),
25            ServiceFilter::ReplicatedMode => FilterItem::new("mode", "replicated".to_string()),
26            ServiceFilter::GlobalMode => FilterItem::new("mode", "global".to_string()),
27            ServiceFilter::Name(n) => FilterItem::new("name", n.to_string()),
28        }
29    }
30}
31
32impl_opts_builder!(url => ServiceList);
33
34impl ServiceListOptsBuilder {
35    impl_filter_func!(ServiceFilter);
36
37    impl_url_bool_field!(
38        /// Include service status, with count of running and desired tasks.
39        status => "status"
40    );
41}
42
43#[derive(Default, Debug)]
44pub struct ServiceOpts {
45    auth: Option<RegistryAuth>,
46    params: HashMap<&'static str, Value>,
47}
48
49impl ServiceOpts {
50    /// return a new instance of a builder for Opts
51    pub fn builder() -> ServiceOptsBuilder {
52        ServiceOptsBuilder::default()
53    }
54
55    /// serialize Opts as a string. returns None if no Opts are defined
56    pub fn serialize(&self) -> Result<String> {
57        serde_json::to_string(&self.params).map_err(Error::from)
58    }
59
60    pub fn serialize_vec(&self) -> Result<Vec<u8>> {
61        serde_json::to_vec(&self.params).map_err(Error::from)
62    }
63
64    pub(crate) fn auth_header(&self) -> Option<String> {
65        self.auth.clone().map(|a| a.serialize())
66    }
67}
68
69#[derive(Default)]
70pub struct ServiceOptsBuilder {
71    auth: Option<RegistryAuth>,
72    params: HashMap<&'static str, Result<Value>>,
73}
74
75impl ServiceOptsBuilder {
76    pub fn name<S>(mut self, name: S) -> Self
77    where
78        S: AsRef<str>,
79    {
80        self.params.insert("Name", Ok(json!(name.as_ref())));
81        self
82    }
83
84    pub fn labels<L, K, V>(mut self, labels: L) -> Self
85    where
86        L: IntoIterator<Item = (K, V)>,
87        K: AsRef<str> + Serialize + Eq + Hash,
88        V: AsRef<str> + Serialize,
89    {
90        self.params.insert(
91            "Labels",
92            Ok(json!(labels.into_iter().collect::<HashMap<_, _>>())),
93        );
94        self
95    }
96
97    pub fn task_template(mut self, spec: &models::TaskSpec) -> Self {
98        self.params.insert("TaskTemplate", to_value_result(spec));
99        self
100    }
101
102    pub fn mode(mut self, mode: &models::ServiceSpecModeInlineItem) -> Self {
103        self.params.insert("Mode", to_value_result(mode));
104        self
105    }
106
107    pub fn update_config(mut self, conf: &models::ServiceSpecUpdateConfigInlineItem) -> Self {
108        self.params.insert("UpdateConfig", to_value_result(conf));
109        self
110    }
111
112    pub fn rollback_config(mut self, conf: &models::ServiceSpecRollbackConfigInlineItem) -> Self {
113        self.params.insert("RollbackConfig", to_value_result(conf));
114        self
115    }
116
117    pub fn networks<N>(mut self, networks: N) -> Self
118    where
119        N: IntoIterator<Item = models::NetworkAttachmentConfig>,
120    {
121        self.params.insert(
122            "Networks",
123            to_value_result(
124                networks
125                    .into_iter()
126                    .collect::<Vec<models::NetworkAttachmentConfig>>(),
127            ),
128        );
129        self
130    }
131
132    pub fn endpoint_spec(mut self, spec: &models::EndpointSpec) -> Self {
133        self.params.insert("EndpointSpec", to_value_result(spec));
134        self
135    }
136
137    pub fn auth(mut self, auth: RegistryAuth) -> Self {
138        self.auth = Some(auth);
139        self
140    }
141
142    pub fn build(self) -> Result<ServiceOpts> {
143        let mut new_params = HashMap::new();
144        for (k, v) in self.params.into_iter() {
145            new_params.insert(k, v?);
146        }
147        Ok(ServiceOpts {
148            auth: self.auth,
149            params: new_params,
150        })
151    }
152}
153
154fn to_value_result<T>(value: T) -> Result<Value>
155where
156    T: Serialize,
157{
158    Ok(serde_json::to_value(value)?)
159}