dockerfile_rs/
macros.rs

1#![allow(non_snake_case)]
2
3/// ```rust,no_run
4/// # use dockerfile_rs::FROM;
5/// let from = FROM!(rust:latest);
6/// assert_eq!(from.to_string(), "FROM rust:latest");
7/// ```
8#[macro_export]
9macro_rules! FROM {
10    ($image:ident) => {{
11        use $crate::From;
12        From {
13            image: stringify!($image).to_string(),
14            tag_or_digest: None,
15            name: None,
16        }
17    }};
18    ($image:ident AS $name:ident) => {{
19        use $crate::From;
20        From {
21            image: stringify!($image).to_string(),
22            tag_or_digest: None,
23            name: Some(stringify!($name).to_string()),
24        }
25    }};
26    ($image:ident:$tag:ident) => {{
27        use $crate::{From, Tag};
28        From {
29            image: stringify!($image).to_string(),
30            tag_or_digest: Some(Tag(stringify!($tag).to_string())),
31            name: None,
32        }
33    }};
34    ($image:ident:$tag:ident AS $name:ident) => {{
35        use $crate::{From, Tag};
36        From {
37            image: stringify!($image).to_string(),
38            tag_or_digest: Some(Tag(stringify!($tag).to_string())),
39            name: Some(stringify!($name).to_string()),
40        }
41    }};
42    ($image:ident@$digest:ident) => {{
43        use $crate::{Digest, From};
44        From {
45            image: stringify!($image).to_string(),
46            tag_or_digest: Some(Digest(stringify!($digest).to_string())),
47            name: None,
48        }
49    }};
50    ($image:ident@$digest:ident AS $name:ident) => {{
51        use $crate::{Digest, From};
52        From {
53            image: stringify!($image).to_string(),
54            tag_or_digest: Some(Digest(stringify!($digest).to_string())),
55            name: Some(stringify!($name).to_string()),
56        }
57    }};
58}
59
60/// ```rust,no_run
61/// # use dockerfile_rs::RUN;
62/// let run = RUN!["echo", "Hello, world!"];
63/// assert_eq!(run.to_string(), r#"RUN ["echo", "Hello, world!"]"#);
64/// ```
65#[macro_export]
66macro_rules! RUN {
67    ($($x:expr), +) => {{
68        use $crate::Run;
69        Run::from(vec![$($x), +])
70    }};
71}
72
73/// ```rust,no_run
74/// # use dockerfile_rs::CMD;
75/// let cmd = CMD!["echo", "Hello, world!"];
76/// assert_eq!(cmd.to_string(), r#"CMD ["echo", "Hello, world!"]"#);
77/// ```
78#[macro_export]
79macro_rules! CMD {
80    ($($x:expr), +) => {{
81        use $crate::Cmd;
82        Cmd::from(vec![$($x), +])
83    }};
84}
85
86/// ```rust,no_run
87/// # use dockerfile_rs::LABEL;
88/// let label = LABEL!["key" => "value"];
89/// assert_eq!(label.to_string(), r#"LABEL key="value""#);
90/// ```
91#[macro_export]
92macro_rules! LABEL {
93    ($($x:expr => $y:expr), +) => {{
94        use $crate::Label;
95        use std::collections::HashMap;
96        let mut map = HashMap::new();
97        $(
98            map.insert($x, $y);
99        )+
100        Label::from(map)
101    }};
102}
103
104/// Deprecated, use [`LABEL!`] with `maintainer` key instead
105/// # Example
106/// ```rust,no_run
107/// # use dockerfile_rs::MAINTAINER;
108/// let maintainer = MAINTAINER!("Rustacean");
109/// assert_eq!(maintainer.to_string(), r#"MAINTAINER Rustacean"#);
110/// ```
111///
112///// [`LABEL!`]: macro.LABEL.html
113#[macro_export]
114macro_rules! MAINTAINER {
115    ($name:expr) => {{
116        use $crate::Maintainer;
117        Maintainer::from($name)
118    }};
119}
120
121/// ```rust,no_run
122/// # use dockerfile_rs::EXPOSE;
123/// let expose = EXPOSE!(5757/udp);
124/// assert_eq!(expose.to_string(), "EXPOSE 5757/udp");
125/// ```
126#[macro_export]
127macro_rules! EXPOSE {
128    ($port:tt/$proto:ident) => {{
129        use $crate::Expose;
130        Expose {
131            port: $port,
132            proto: Some(stringify!($proto).to_string()),
133        }
134    }};
135    ($port:expr) => {{
136        use $crate::Expose;
137        Expose::from($port)
138    }};
139}
140
141/// ```rust,no_run
142/// # use dockerfile_rs::ENV;
143/// let env = ENV!["BUILD" => "true"];
144/// assert_eq!(env.to_string(), r#"ENV BUILD="true""#);
145/// ```
146#[macro_export]
147macro_rules! ENV {
148    ($($x:expr => $y:expr), +) => {{
149        use $crate::Env;
150        use std::collections::HashMap;
151        let mut map = HashMap::new();
152        $(
153            map.insert($x, $y);
154        )+
155        Env::from(map)
156    }};
157}
158
159/// ```rust,no_run
160/// # use dockerfile_rs::ADD;
161/// let add = ADD!("/var/run" "/home");
162/// assert_eq!(add.to_string(), r#"ADD "/var/run" "/home""#);
163/// ```
164#[macro_export]
165macro_rules! ADD {
166    (--chown=$user:ident:$group:ident $src:tt $dst:tt) => {{
167        use $crate::{Add, User};
168        Add {
169            src: $src.to_string(),
170            dst: $dst.to_string(),
171            chown: Some(User {
172                user: stringify!($user).to_string(),
173                group: Some(stringify!($group).to_string()),
174            }),
175        }
176    }};
177    (--chown=$user:ident $src:tt $dst:tt) => {{
178        use $crate::{Add, User};
179        Add {
180            src: $src.to_string(),
181            dst: $dst.to_string(),
182            chown: Some(User {
183                user: stringify!($user).to_string(),
184                group: None,
185            }),
186        }
187    }};
188    ($src:tt $dst:tt) => {{
189        use $crate::Add;
190        Add {
191            src: $src.to_string(),
192            dst: $dst.to_string(),
193            chown: None,
194        }
195    }};
196}
197
198/// ```rust,no_run
199/// # use dockerfile_rs::COPY;
200/// let copy = COPY!("." ".");
201/// assert_eq!(copy.to_string(), r#"COPY "." ".""#);
202/// ```
203#[macro_export]
204macro_rules! COPY {
205    (--from=$name:ident --chown=$user:ident:$group:ident $src:tt $dst:tt) => {{
206        use $crate::{Copy, User};
207        Copy {
208            src: $src.to_string(),
209            dst: $dst.to_string(),
210            from: Some(stringify!($from).to_string()),
211            chown: Some(User {
212                user: stringify!($user).to_string(),
213                group: Some(stringify!($group).to_string()),
214            }),
215        }
216    }};
217    (--from=$name:ident --chown=$user:ident $src:tt $dst:tt) => {{
218        use $crate::{Copy, User};
219        Copy {
220            src: $src.to_string(),
221            dst: $dst.to_string(),
222            from: Some(stringify!($from).to_string()),
223            chown: Some(User {
224                user: stringify!($user).to_string(),
225                group: None,
226            }),
227        }
228    }};
229    (--chown=$user:ident:$group:ident $src:tt $dst:tt) => {{
230        use $crate::{Copy, User};
231        Copy {
232            src: $src.to_string(),
233            dst: $dst.to_string(),
234            from: None,
235            chown: Some(User {
236                user: stringify!($user).to_string(),
237                group: Some(stringify!($group).to_string()),
238            }),
239        }
240    }};
241    (--chown=$user:ident $src:tt $dst:tt) => {{
242        use $crate::{Copy, User};
243        Copy {
244            src: $src.to_string(),
245            dst: $dst.to_string(),
246            from: None,
247            chown: Some(User {
248                user: stringify!($user).to_string(),
249                group: None,
250            }),
251        }
252    }};
253    ($src:tt $dst:tt) => {{
254        use $crate::Copy;
255        Copy {
256            src: $src.to_string(),
257            dst: $dst.to_string(),
258            from: None,
259            chown: None,
260        }
261    }};
262}
263
264/// ```rust,no_run
265/// # use dockerfile_rs::ENTRYPOINT;
266/// let entry_point = ENTRYPOINT!["/bin/bash/", "-c", "echo"];
267/// assert_eq!(entry_point.to_string(), r#"ENTRYPOINT ["/bin/bash/", "-c", "echo"]"#);
268/// ```
269#[macro_export]
270macro_rules! ENTRYPOINT {
271    ($($x:expr), +) => {{
272        use $crate::EntryPoint;
273        EntryPoint::from(vec![$($x), +])
274    }};
275}
276
277/// ```rust,no_run
278/// # use dockerfile_rs::VOLUME;
279/// let volume = VOLUME!("/var/run", "/var/www");
280/// assert_eq!(volume.to_string(), r#"VOLUME ["/var/run", "/var/www"]"#);
281/// ```
282#[macro_export]
283macro_rules! VOLUME {
284    ($($x:expr), +) => {{
285        use $crate::Volume;
286        Volume::from(vec![$($x), +])
287    }};
288}
289
290/// ```rust,no_run
291/// # use dockerfile_rs::USER;
292/// let user = USER!(rustacean);
293/// assert_eq!(user.to_string(), r#"USER rustacean"#);
294/// ```
295#[macro_export]
296macro_rules! USER {
297    ($user:ident:$group:ident) => {{
298        use $crate::User;
299        User {
300            user: stringify!($user).to_string(),
301            group: Some(stringify!($group).to_string()),
302        }
303    }};
304    ($user:ident) => {{
305        use $crate::User;
306        User {
307            user: stringify!($user).to_string(),
308            group: None,
309        }
310    }};
311}
312
313/// ```rust,no_run
314/// # use dockerfile_rs::WORKDIR;
315/// let work_dir = WORKDIR!("/home/container001");
316/// assert_eq!(work_dir.to_string(), r#"WORKDIR "/home/container001""#);
317/// ```
318#[macro_export]
319macro_rules! WORKDIR {
320    ($dir:expr) => {{
321        use $crate::WorkDir;
322        WorkDir::from($dir)
323    }};
324}
325
326/// ```rust,no_run
327/// # use dockerfile_rs::ARG;
328/// let arg = ARG!("key" => "value");
329/// assert_eq!(arg.to_string(), r#"ARG key="value""#);
330/// ```
331#[macro_export]
332macro_rules! ARG {
333    ($x:expr => $y:expr) => {{
334        use $crate::Arg;
335        Arg::from(($x, $y))
336    }};
337}
338
339/// ```rust,no_run
340/// # use dockerfile_rs::STOPSIGNAL;
341/// let signal = STOPSIGNAL!("SIGKILL");
342/// assert_eq!(signal.to_string(), "STOPSIGNAL SIGKILL");
343/// ```
344#[macro_export]
345macro_rules! STOPSIGNAL {
346    ($signal:expr) => {{
347        use $crate::StopSignal;
348        StopSignal::from($signal)
349    }};
350}
351
352/// ```rust,no_run
353/// # use dockerfile_rs::HEALTHCHECK;
354/// let health_check = HEALTHCHECK!(NONE);
355/// assert_eq!(health_check.to_string(), "HEALTHCHECK NONE");
356/// ```
357#[macro_export]
358macro_rules! HEALTHCHECK {
359    (NONE) => {{
360        use $crate::HealthCheck;
361        HealthCheck::None
362    }};
363    (CMD $cmd:expr) => {{
364        use $crate::{Cmd, HealthCheck};
365        HealthCheck::Check {
366            cmd: Cmd::from($cmd),
367            interval: None,
368            timeout: None,
369            start_period: None,
370            retries: None,
371        }
372    }};
373}
374
375/// ```rust,no_run
376/// # use dockerfile_rs::SHELL;
377/// let shell = SHELL!["/bin/bash", "-c"];
378/// assert_eq!(shell.to_string(), r#"SHELL ["/bin/bash", "-c"]"#);
379/// ```
380#[macro_export]
381macro_rules! SHELL {
382    ($($x:expr), +) => {{
383        use $crate::Shell;
384        Shell::from(vec![$($x), +])
385    }};
386}
387
388/// ```rust,no_run
389/// # use dockerfile_rs::ONBUILD;
390/// # use dockerfile_rs::ENV;
391/// let on_build = ONBUILD!(ENV!["key" => "value"]);
392/// assert_eq!(on_build.to_string(), r#"ONBUILD ENV key="value""#);
393/// ```
394#[macro_export]
395macro_rules! ONBUILD {
396    ($x:expr) => {{
397        use $crate::OnBuild;
398        OnBuild::from($x)
399    }};
400}
401
402/// ```rust,no_run
403/// # use dockerfile_rs::COMMENT;
404/// let comment = COMMENT!("Hello!");
405/// assert_eq!(comment.to_string(), "# Hello!");
406/// ```
407#[macro_export]
408macro_rules! COMMENT {
409    ($x:expr) => {{
410        use $crate::Comment;
411        Comment::from($x)
412    }};
413}
414
415mod tests {
416    #[test]
417    fn from() {
418        let _ = FROM!(rust);
419        let _ = FROM!(rust AS crab);
420        let _ = FROM!(rust: latest);
421        let _ = FROM!(rust:latest AS crab);
422        let _ = FROM!(rust@digest);
423        let _ = FROM!(rust@digest AS crab);
424    }
425
426    #[test]
427    fn run() {
428        let _ = RUN!["/bin/bash", "-c", "echo"];
429    }
430
431    #[test]
432    fn cmd() {
433        let _ = CMD!["echo", "Hello, world!"];
434    }
435
436    #[test]
437    fn label() {
438        let _ = LABEL!["key" => "value"];
439        let _ = LABEL!["key" => "value", "hello" => "world"];
440    }
441
442    #[test]
443    fn maintainer() {
444        let _ = MAINTAINER!("Funny Rustacean");
445    }
446
447    #[test]
448    fn expose() {
449        let _ = EXPOSE!(80 / tcp);
450        let _ = EXPOSE!(443);
451    }
452
453    #[test]
454    fn env() {
455        let _ = ENV!["key" => "value"];
456        let _ = ENV!["key" => "value", "hello" => "world"];
457    }
458
459    #[test]
460    fn add() {
461        let _ = ADD!(--chown=rustacean:root "/var/run" "/home");
462        let _ = ADD!(--chown=rustacean "/var/run" "/home");
463        let _ = ADD!("/var/run" "/home");
464    }
465
466    #[test]
467    fn copy() {
468        let _ = COPY!(--from=crab --chown=rustacean:root "/var/run" "/home");
469        let _ = COPY!(--from=crab --chown=rustacean "/var/run" "/home");
470        let _ = COPY!(--chown=rustacean:root "/var/run" "/home");
471        let _ = COPY!(--chown=rustacean "/var/run" "/home");
472        let _ = COPY!("/var/run" "/home");
473    }
474
475    #[test]
476    fn entry_point() {
477        let _ = ENTRYPOINT!["echo", "Hello, world!"];
478    }
479
480    #[test]
481    fn volume() {
482        let _ = VOLUME!["/var/run", "/home"];
483    }
484
485    #[test]
486    fn user() {
487        let _ = USER!(rustacean: root);
488        let _ = USER!(rustacean);
489    }
490
491    #[test]
492    fn work_dir() {
493        let _ = WORKDIR!("/home/rustacean");
494    }
495
496    #[test]
497    fn arg() {
498        let _ = ARG!("key" => "value");
499    }
500
501    #[test]
502    fn stop_signal() {
503        let _ = STOPSIGNAL!("SIGKILL");
504    }
505
506    #[test]
507    fn health_check() {
508        let _ = HEALTHCHECK!(NONE);
509        let _ = HEALTHCHECK!(CMD vec!["curl", "-v", "https://rust-lang.org"]);
510    }
511
512    #[test]
513    fn shell() {
514        let _ = SHELL!["/bin/bash", "-c"];
515    }
516
517    #[test]
518    fn on_build() {
519        let on_build = ONBUILD!(CMD!["echo", "Hello, world!"]);
520        assert_eq!(
521            on_build.to_string(),
522            r#"ONBUILD CMD ["echo", "Hello, world!"]"#
523        );
524    }
525
526    #[test]
527    fn comment() {
528        let _ = COMMENT!("Hello, world!");
529    }
530}