1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use std::{
borrow::Cow,
fmt,
};
use crate::{
instructions::{
Arg,
Directive,
From,
Instruction,
},
};
pub struct Dockerfile(Vec<Instruction>);
impl fmt::Display for Dockerfile {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0.iter().fold(String::new(), |acc, elem| acc + &elem.to_string()))
}
}
impl Dockerfile {
pub fn base<T: Into<Cow<'static, str>>>(from: T) -> DockerfileBuilder {
DockerfileBuilder{
initial_directives: None,
initial_args: None,
from: From::new(from),
instructions: None,
}
}
}
pub struct DockerfileBuilder {
initial_directives: Option<Vec<Directive>>,
initial_args: Option<Vec<Arg>>,
from: From,
instructions: Option<Vec<Instruction>>,
}
impl DockerfileBuilder {
pub fn push_initial_directive(mut self, directive: Directive) -> Self {
if let Some(ref mut directives) = self.initial_directives {
directives.push(directive);
} else {
self.initial_directives = Some(vec![directive]);
}
self
}
pub fn push_initial_arg(mut self, arg: Arg) -> Self {
if let Some(ref mut args) = self.initial_args {
args.push(arg);
} else {
self.initial_args = Some(vec![arg]);
}
self
}
pub fn push<I: Into<Instruction>>(mut self, instruction: I) -> Self {
if let Some(ref mut instructions) = self.instructions {
instructions.push(instruction.into());
} else {
self.instructions = Some(vec![instruction.into()]);
}
self
}
pub fn append<I: Into<Instruction>>(mut self, new: Vec<I>) -> Self {
let mut new = new.into_iter().map(Into::into).collect();
if let Some(ref mut instructions) = self.instructions {
instructions.append(&mut new);
} else {
self.instructions = Some(new);
}
self
}
pub fn finish(self) -> Dockerfile {
let mut all_instructions: Vec<Instruction> = vec![];
if let Some(directives) = self.initial_directives {
all_instructions.extend(directives.into_iter().map(|inst| Instruction::Directive(inst)));
}
if let Some(args) = self.initial_args {
all_instructions.extend(args.into_iter().map(|inst| Instruction::Arg(inst)));
}
all_instructions.push(Instruction::From(self.from));
if let Some(instructions) = self.instructions {
all_instructions.extend(instructions.into_iter());
}
Dockerfile(all_instructions)
}
}