1use crate::{models::Ipam, Error, Result};
2use containers_api::opts::{Filter, FilterItem};
3use containers_api::{
4 impl_field, impl_filter_func, impl_map_field, impl_opts_builder, impl_str_field, impl_vec_field,
5};
6
7use std::{collections::HashMap, convert::AsRef};
8
9use serde::Serialize;
10use serde_json::{json, Value};
11
12impl_opts_builder!(url =>
13 NetworkList
15);
16
17pub enum Scope {
19 Swarm,
20 Global,
21 Local,
22}
23
24impl AsRef<str> for Scope {
25 fn as_ref(&self) -> &str {
26 match &self {
27 Scope::Swarm => "swarm",
28 Scope::Global => "global",
29 Scope::Local => "local",
30 }
31 }
32}
33
34pub enum NetworkType {
35 Custom,
36 Builtin,
37}
38
39impl AsRef<str> for NetworkType {
40 fn as_ref(&self) -> &str {
41 match &self {
42 NetworkType::Custom => "custom",
43 NetworkType::Builtin => "builtin",
44 }
45 }
46}
47
48pub enum NetworkFilter {
50 Dangling(bool),
53 Driver(String),
55 Id(String),
57 LabelKey(String),
59 LabelKeyVal(String, String),
61 Name(String),
63 Scope(Scope),
64 Type(NetworkType),
65}
66
67impl Filter for NetworkFilter {
68 fn query_item(&self) -> FilterItem {
69 use NetworkFilter::*;
70
71 match &self {
72 Dangling(dangling) => FilterItem::new("dangling", dangling.to_string()),
73 Driver(driver) => FilterItem::new("driver", driver.to_owned()),
74 Id(id) => FilterItem::new("id", id.to_owned()),
75 LabelKey(key) => FilterItem::new("label", key.to_owned()),
76 LabelKeyVal(key, val) => FilterItem::new("label", format!("{key}={val}")),
77 Name(name) => FilterItem::new("name", name.to_owned()),
78 Scope(scope) => FilterItem::new("scope", scope.as_ref().to_owned()),
79 Type(type_) => FilterItem::new("type", type_.as_ref().to_owned()),
80 }
81 }
82}
83
84impl NetworkListOptsBuilder {
85 impl_filter_func!(
86 NetworkFilter
88 );
89}
90
91#[derive(Serialize, Debug, Clone)]
93pub struct NetworkCreateOpts {
94 params: HashMap<&'static str, Value>,
95}
96
97impl NetworkCreateOpts {
98 pub fn builder<N>(name: N) -> NetworkCreateOptsBuilder
100 where
101 N: AsRef<str>,
102 {
103 NetworkCreateOptsBuilder::new(name.as_ref())
104 }
105
106 pub fn serialize(&self) -> Result<String> {
108 serde_json::to_string(&self.params).map_err(Error::from)
109 }
110
111 pub fn serialize_vec(&self) -> Result<Vec<u8>> {
113 serde_json::to_vec(&self.params).map_err(Error::from)
114 }
115}
116
117#[derive(Default)]
118pub struct NetworkCreateOptsBuilder {
119 params: HashMap<&'static str, Value>,
120}
121
122impl NetworkCreateOptsBuilder {
123 pub(crate) fn new(name: &str) -> Self {
124 let mut params = HashMap::new();
125 params.insert("Name", json!(name));
126 NetworkCreateOptsBuilder { params }
127 }
128
129 impl_field!(
130 check_duplicate: bool => "CheckDuplicate"
136 );
137
138 impl_str_field!(
139 driver => "Driver"
141 );
142
143 impl_field!(
144 internal: bool => "Internal"
146 );
147
148 impl_field!(
149 attachable: bool => "Attachable"
152 );
153
154 impl_field!(
155 ingress: bool => "Ingress"
157 );
158
159 impl_field!(
160 enable_ipv6: bool => "EnableIPv6"
162 );
163
164 impl_map_field!(json
165 options => "Options"
167 );
168
169 impl_map_field!(json
170 labels => "Labels"
172 );
173
174 impl_field!(
175 ipam: Ipam => "IPAM"
177 );
178
179 pub fn build(&self) -> NetworkCreateOpts {
180 NetworkCreateOpts {
181 params: self.params.clone(),
182 }
183 }
184}
185#[derive(Serialize, Debug)]
186pub struct ContainerDisconnectionOpts {
188 params: HashMap<&'static str, Value>,
189}
190
191impl ContainerDisconnectionOpts {
192 pub fn serialize(&self) -> Result<String> {
194 serde_json::to_string(&self.params).map_err(Error::from)
195 }
196
197 pub fn serialize_vec(&self) -> Result<Vec<u8>> {
199 serde_json::to_vec(&self.params).map_err(Error::from)
200 }
201
202 pub fn builder<I>(container_id: I) -> ContainerDisconnectionOptsBuilder
204 where
205 I: AsRef<str>,
206 {
207 ContainerDisconnectionOptsBuilder::new(container_id.as_ref())
208 }
209}
210
211#[derive(Default)]
212pub struct ContainerDisconnectionOptsBuilder {
213 params: HashMap<&'static str, Value>,
214}
215
216impl ContainerDisconnectionOptsBuilder {
217 pub(crate) fn new(container_id: &str) -> Self {
218 ContainerDisconnectionOptsBuilder {
219 params: [("Container", json!(container_id.to_string()))].into(),
220 }
221 }
222
223 impl_field!(
224 force: bool => "Force"
226 );
227
228 pub fn build(self) -> ContainerDisconnectionOpts {
229 ContainerDisconnectionOpts {
230 params: self.params,
231 }
232 }
233}
234
235#[derive(Serialize, Debug)]
236pub struct ContainerConnectionOpts {
238 params: HashMap<&'static str, Value>,
239}
240
241impl ContainerConnectionOpts {
242 pub fn serialize(&self) -> Result<String> {
244 serde_json::to_string(&self.params).map_err(Error::from)
245 }
246
247 pub fn serialize_vec(&self) -> Result<Vec<u8>> {
249 serde_json::to_vec(&self.params).map_err(Error::from)
250 }
251
252 pub fn builder<I>(container_id: I) -> ContainerConnectionOptsBuilder
254 where
255 I: AsRef<str>,
256 {
257 ContainerConnectionOptsBuilder::new(container_id.as_ref())
258 }
259}
260
261#[derive(Default)]
262pub struct ContainerConnectionOptsBuilder {
263 params: HashMap<&'static str, Value>,
264 container: String,
265}
266
267impl ContainerConnectionOptsBuilder {
268 pub(crate) fn new(container_id: &str) -> Self {
269 ContainerConnectionOptsBuilder {
270 params: HashMap::new(),
271 container: container_id.to_string(),
272 }
273 }
274
275 pub fn ipam_config(mut self, config: EndpointIpamConfig) -> Self {
277 self.params.insert("EndpointConfig", json!(config.params));
278 self
279 }
280
281 impl_vec_field!(aliases => "Aliases");
282
283 impl_vec_field!(links => "Links");
284
285 impl_str_field!(
286 network_id => "NetworkID"
288 );
289
290 impl_str_field!(
291 endpoint_id => "EndpointID"
293 );
294
295 impl_str_field!(
296 gateway => "Gateway"
298 );
299
300 impl_str_field!(
301 ipv4 => "IPAddress"
303 );
304
305 impl_field!(
306 prefix_len: isize => "IPPrefixLen"
308 );
309
310 impl_str_field!(
311 ipv6_gateway => "IPv6Gateway"
313 );
314
315 impl_str_field!(
316 ipv6 => "GlobalIPv6Address"
318 );
319
320 impl_field!(
321 ipv6_prefix_len: i64 => "GlobalIPv6PrefixLen"
323 );
324
325 impl_str_field!(
326 mac => "MacAddress"
328 );
329
330 impl_map_field!(json
331 driver_opts => "DriverOpts"
334 );
335
336 pub fn build(self) -> ContainerConnectionOpts {
337 let mut params = HashMap::new();
338 params.insert("EndpointConfig", json!(self.params));
339 params.insert("Container", json!(self.container));
340 ContainerConnectionOpts { params }
341 }
342}
343
344#[derive(Default)]
345pub struct EndpointIpamConfig {
348 params: HashMap<&'static str, serde_json::Value>,
349}
350
351impl EndpointIpamConfig {
352 pub fn new() -> Self {
353 Self::default()
354 }
355
356 pub fn ipv4<A>(mut self, address: A) -> Self
357 where
358 A: Into<String>,
359 {
360 self.params.insert("IPv4Address", json!(address.into()));
361 self
362 }
363
364 pub fn ipv6<A>(mut self, address: A) -> Self
365 where
366 A: Into<String>,
367 {
368 self.params.insert("IPv6Address", json!(address.into()));
369 self
370 }
371
372 pub fn link_local_ips<I>(mut self, ips: I) -> Self
373 where
374 I: IntoIterator,
375 I::Item: Into<String>,
376 {
377 self.params.insert(
378 "LinkLocalIPs",
379 json!(ips.into_iter().map(I::Item::into).collect::<Vec<_>>()),
380 );
381 self
382 }
383}
384
385impl_opts_builder!(url => NetworkPrune);
386
387pub enum NetworkPruneFilter {
388 Until(String),
392 #[cfg(feature = "chrono")]
393 #[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
394 UntilDate(chrono::DateTime<chrono::Utc>),
396 LabelKey(String),
398 Label(String, String),
400}
401
402impl Filter for NetworkPruneFilter {
403 fn query_item(&self) -> FilterItem {
404 use NetworkPruneFilter::*;
405 match &self {
406 Until(until) => FilterItem::new("until", until.to_owned()),
407 #[cfg(feature = "chrono")]
408 UntilDate(until) => FilterItem::new("until", until.timestamp().to_string()),
409 LabelKey(label) => FilterItem::new("label", label.to_owned()),
410 Label(key, val) => FilterItem::new("label", format!("{key}={val}")),
411 }
412 }
413}
414
415impl NetworkPruneOptsBuilder {
416 impl_filter_func!(
417 NetworkPruneFilter
419 );
420}