stackify_docker_api/opts/
mod.rs

1//! Options used for configuring the behavior of certain API endpoints
2mod container;
3mod exec;
4mod image;
5mod network;
6mod system;
7mod volume;
8
9#[cfg(feature = "swarm")]
10#[cfg_attr(docsrs, doc(cfg(feature = "swarm")))]
11mod config;
12#[cfg(feature = "swarm")]
13#[cfg_attr(docsrs, doc(cfg(feature = "swarm")))]
14mod node;
15#[cfg(feature = "swarm")]
16#[cfg_attr(docsrs, doc(cfg(feature = "swarm")))]
17mod plugin;
18#[cfg(feature = "swarm")]
19#[cfg_attr(docsrs, doc(cfg(feature = "swarm")))]
20mod secret;
21#[cfg(feature = "swarm")]
22#[cfg_attr(docsrs, doc(cfg(feature = "swarm")))]
23mod service;
24#[cfg(feature = "swarm")]
25#[cfg_attr(docsrs, doc(cfg(feature = "swarm")))]
26mod swarm;
27#[cfg(feature = "swarm")]
28#[cfg_attr(docsrs, doc(cfg(feature = "swarm")))]
29mod task;
30
31pub use container::*;
32pub use exec::*;
33pub use image::*;
34pub use network::*;
35pub use system::*;
36pub use volume::*;
37
38#[cfg(feature = "swarm")]
39pub use config::*;
40#[cfg(feature = "swarm")]
41pub use node::*;
42#[cfg(feature = "swarm")]
43pub use plugin::*;
44#[cfg(feature = "swarm")]
45pub use secret::*;
46#[cfg(feature = "swarm")]
47pub use service::*;
48#[cfg(feature = "swarm")]
49pub use swarm::*;
50#[cfg(feature = "swarm")]
51pub use task::*;
52
53use containers_api::{impl_opts_builder, impl_url_bool_field, impl_url_field};
54
55impl_opts_builder!(url => Logs);
56
57impl LogsOptsBuilder {
58    impl_url_bool_field!(
59        /// Keep connection after returning logs.
60        follow => "follow"
61    );
62
63    impl_url_bool_field!(
64        /// Return logs from `stdout`.
65        stdout => "stdout"
66    );
67
68    impl_url_bool_field!(
69        /// Return logs from `stderr`.
70        stderr => "stderr"
71    );
72
73    impl_url_bool_field!(
74        /// Add timestamps to every log line.
75        timestamps => "timestamps"
76    );
77
78    impl_url_field!(
79        /// Only return this number of log lines from the end of logs
80        n_lines: usize => "tail"
81    );
82
83    /// Return all log lines.
84    pub fn all(mut self) -> Self {
85        self.params.insert("tail", "all".into());
86        self
87    }
88
89    #[cfg(feature = "chrono")]
90    /// Only return logs since this time.
91    pub fn since<Tz>(mut self, timestamp: &chrono::DateTime<Tz>) -> Self
92    where
93        Tz: chrono::TimeZone,
94    {
95        self.params
96            .insert("since", timestamp.timestamp().to_string());
97        self
98    }
99
100    #[cfg(not(feature = "chrono"))]
101    /// Only return logs since this time, as a UNIX timestamp.
102    pub fn since(mut self, timestamp: i64) -> Self {
103        self.params.insert("since", timestamp.to_string());
104        self
105    }
106
107    #[cfg(feature = "chrono")]
108    /// Only return logs before this time.
109    pub fn until<Tz>(mut self, timestamp: &chrono::DateTime<Tz>) -> Self
110    where
111        Tz: chrono::TimeZone,
112    {
113        self.params
114            .insert("until", timestamp.timestamp().to_string());
115        self
116    }
117
118    #[cfg(not(feature = "chrono"))]
119    /// Only return logs before this time, as a UNIX timestamp.
120    pub fn until(mut self, timestamp: i64) -> Self {
121        self.params.insert("until", timestamp.to_string());
122        self
123    }
124}
125
126#[cfg(test)]
127mod tests {
128    use super::*;
129    #[cfg(feature = "chrono")]
130    #[test]
131    fn logs_options() {
132        let timestamp = chrono::NaiveDateTime::from_timestamp_opt(2_147_483_647, 0);
133        let since = chrono::DateTime::<chrono::Utc>::from_utc(timestamp.unwrap(), chrono::Utc);
134
135        let options = LogsOptsBuilder::default()
136            .follow(true)
137            .stdout(true)
138            .stderr(true)
139            .timestamps(true)
140            .all()
141            .since(&since)
142            .build();
143
144        let serialized = options.serialize().unwrap();
145
146        assert!(serialized.contains("follow=true"));
147        assert!(serialized.contains("stdout=true"));
148        assert!(serialized.contains("stderr=true"));
149        assert!(serialized.contains("timestamps=true"));
150        assert!(serialized.contains("tail=all"));
151        assert!(serialized.contains("since=2147483647"));
152
153        let options = LogsOptsBuilder::default().n_lines(5).until(&since).build();
154
155        let serialized = options.serialize().unwrap();
156
157        assert!(serialized.contains("tail=5"));
158        assert!(serialized.contains("until=2147483647"));
159    }
160
161    #[cfg(not(feature = "chrono"))]
162    #[test]
163    fn logs_options() {
164        let options = LogsOptsBuilder::default()
165            .follow(true)
166            .stdout(true)
167            .stderr(true)
168            .timestamps(true)
169            .all()
170            .since(2_147_483_647)
171            .until(2_147_600_000)
172            .build();
173
174        let serialized = options.serialize().unwrap();
175
176        assert!(serialized.contains("follow=true"));
177        assert!(serialized.contains("stdout=true"));
178        assert!(serialized.contains("stderr=true"));
179        assert!(serialized.contains("timestamps=true"));
180        assert!(serialized.contains("tail=all"));
181        assert!(serialized.contains("since=2147483647"));
182        assert!(serialized.contains("until=2147600000"));
183    }
184}