1#![allow(non_snake_case)]
2
3#[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#[macro_export]
66macro_rules! RUN {
67 ($($x:expr), +) => {{
68 use $crate::Run;
69 Run::from(vec![$($x), +])
70 }};
71}
72
73#[macro_export]
79macro_rules! CMD {
80 ($($x:expr), +) => {{
81 use $crate::Cmd;
82 Cmd::from(vec![$($x), +])
83 }};
84}
85
86#[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#[macro_export]
114macro_rules! MAINTAINER {
115 ($name:expr) => {{
116 use $crate::Maintainer;
117 Maintainer::from($name)
118 }};
119}
120
121#[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#[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#[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#[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#[macro_export]
270macro_rules! ENTRYPOINT {
271 ($($x:expr), +) => {{
272 use $crate::EntryPoint;
273 EntryPoint::from(vec![$($x), +])
274 }};
275}
276
277#[macro_export]
283macro_rules! VOLUME {
284 ($($x:expr), +) => {{
285 use $crate::Volume;
286 Volume::from(vec![$($x), +])
287 }};
288}
289
290#[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#[macro_export]
319macro_rules! WORKDIR {
320 ($dir:expr) => {{
321 use $crate::WorkDir;
322 WorkDir::from($dir)
323 }};
324}
325
326#[macro_export]
332macro_rules! ARG {
333 ($x:expr => $y:expr) => {{
334 use $crate::Arg;
335 Arg::from(($x, $y))
336 }};
337}
338
339#[macro_export]
345macro_rules! STOPSIGNAL {
346 ($signal:expr) => {{
347 use $crate::StopSignal;
348 StopSignal::from($signal)
349 }};
350}
351
352#[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#[macro_export]
381macro_rules! SHELL {
382 ($($x:expr), +) => {{
383 use $crate::Shell;
384 Shell::from(vec![$($x), +])
385 }};
386}
387
388#[macro_export]
395macro_rules! ONBUILD {
396 ($x:expr) => {{
397 use $crate::OnBuild;
398 OnBuild::from($x)
399 }};
400}
401
402#[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}