Skip to main content

nanite_docker/instruction/
copy.rs

1use alloc::format;
2use alloc::string::String;
3use alloc::vec::Vec;
4use core::fmt::{Display, Formatter, Write};
5
6/// Represents a `COPY` instruction
7///
8/// ```rust
9/// use nanite_docker::{Copy, CopyOpt};
10///
11/// let copy = Copy {
12///     opts: vec![
13///         CopyOpt::From { stage: "stage".to_string() },
14///         CopyOpt::Link,
15///     ],
16///     src: vec![
17///         "src1".to_string(),
18///         "src2".to_string(),
19///     ],
20///     dest: "dest".to_string(),
21/// };
22/// let copy_built = format!("{copy}");
23/// assert_eq!(copy_built, r#"COPY --from=stage --link "src1" "src2" "dest""#);
24/// ```
25#[derive(Clone, Debug)]
26pub struct Copy {
27    pub opts: Vec<CopyOpt>,
28    pub src: Vec<String>,
29    pub dest: String,
30}
31
32// I know this is the same as it is for Add, I haven't found a cleaner way yet
33impl Display for Copy {
34    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
35        let mut opt_string = String::new();
36
37        for opt in &self.opts {
38            // Add a space to the end (THIS IS NOT A BUG)
39            write!(opt_string, "{opt} ")?;
40        }
41
42        let src_string = self
43            .src
44            .iter()
45            .map(|i| format!(r#""{i}""#))
46            .collect::<Vec<String>>()
47            .join(" ");
48
49        write!(f, r#"COPY {opt_string}{src_string} "{}""#, self.dest)
50    }
51}
52
53#[derive(Clone, Debug)]
54pub enum CopyOpt {
55    From { stage: String },
56    Chown { user: String, group: Option<String> },
57    Chmod { perms: String },
58    Link,
59    Parents,
60    Exclude { path: String },
61}
62
63impl Display for CopyOpt {
64    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
65        match self {
66            CopyOpt::From { stage: s } => write!(f, "--from={s}"),
67
68            CopyOpt::Chown { user: u, group: g } => match g {
69                Some(group) => write!(f, "--chown={u}:{group}"),
70                None => write!(f, "--chown={u}"),
71            },
72
73            CopyOpt::Chmod { perms: p } => write!(f, "--chmod={p}"),
74
75            CopyOpt::Link => write!(f, "--link"),
76
77            CopyOpt::Parents => write!(f, "--parents"),
78
79            CopyOpt::Exclude { path: p } => write!(f, r#"--exclude="{p}""#),
80        }
81    }
82}