docker_generate/
docker.rs

1
2
3macro_rules! str_arr_to_string_vec {
4    ($i:ident) => ($i.iter().map(|a| a.to_string()).collect::<Vec<String>>())
5}
6
7pub enum DockerFieldType<'a>{
8    Docker(DockerFile<'a>),
9    r#String(String),
10    Array(Vec<&'a str>),
11    TupleList(&'a[(&'a str, &'a str)]),
12    MultiValue(Vec<String>),
13    Protocal((i32, &'a str)),
14    Int(i32),
15}
16
17impl<'a> From<Vec<String>> for DockerFieldType<'a>{
18    fn from(value: Vec<String>) -> Self {
19        DockerFieldType::MultiValue(value)
20    }
21}
22
23impl<'a> From<Vec<&'a str>> for DockerFieldType<'a>{
24    fn from(value: Vec<&'a str>) -> Self {
25        DockerFieldType::MultiValue(str_arr_to_string_vec!(value))
26    }
27}
28
29
30impl<'a> From<&'a [&'a str]> for DockerFieldType<'a>{
31    fn from(value: &'a [&'a str]) -> Self {
32        DockerFieldType::MultiValue(str_arr_to_string_vec!(value))
33    }
34}
35
36impl<'a> From<&'a str> for DockerFieldType<'a>{
37    fn from(value: &'a str) -> Self {
38        DockerFieldType::String(value.to_string())
39    }
40}
41
42impl<'a> From<String> for DockerFieldType<'a>{
43    fn from(value: String) -> Self {
44        DockerFieldType::String(value)
45    }
46}
47
48impl<'a> From<DockerFile<'a>> for DockerFieldType<'a>{
49    fn from(value: DockerFile<'a>) -> Self {
50        DockerFieldType::Docker(value)
51    }
52}
53
54impl<'a> From<&'a[(&'a str, &'a str)]> for DockerFieldType<'a>{
55    fn from(value: &'a[(&'a str, &'a str)]) -> Self {
56        DockerFieldType::TupleList(value)
57    }
58}
59
60impl<'a> From<(i32, &'a str)> for DockerFieldType<'a>{
61    fn from(value: (i32, &'a str)) -> Self {
62        DockerFieldType::Protocal(value)
63    }
64}
65
66impl<'a> From<i32> for DockerFieldType<'a>{
67    fn from(value: i32) -> Self {
68        DockerFieldType::Int(value)
69    }
70}
71
72impl <'a> DockerFieldType<'a>{
73    pub fn to_string(&self) -> String{
74        match self {
75            DockerFieldType::Docker(d) => d.to_string(),
76            DockerFieldType::String(s) => s.to_string(),
77            DockerFieldType::Int(i) => i.to_string(),
78            DockerFieldType::Protocal((i,p)) => format!("{}/{}", i.to_string(), p),
79            DockerFieldType::TupleList(l) => l.into_iter()
80                                            .map(|(v1,v2)| format!("{}=\"{}\"", v1,v2))
81                                            .collect::<Vec<String>>()
82                                            .join(" "),
83            DockerFieldType::Array(arr) =>  format!("[{}]", 
84                                            arr.into_iter()
85                                            .map(|i| format!("\"{}\"", i))
86                                            .collect::<Vec<String>>()
87                                            .join(", ")),
88            DockerFieldType::MultiValue(arr) => arr.join(" "), 
89        }
90    }
91}
92
93pub struct DockerField<'a>{
94    name: &'a str,
95    value: DockerFieldType<'a>
96}
97
98impl<'a> DockerField<'a> {
99    fn new(name: &'a str, value: DockerFieldType<'a>) -> Self{
100        DockerField{
101            name: name,
102            value: value,
103        }
104    }
105}
106
107pub struct DockerFile<'a>{
108    fields: Vec<DockerField<'a>>,
109}
110
111impl<'a> Default for DockerFile<'a>{
112    fn default() -> Self {
113        DockerFile{
114            fields: Vec::new(),
115        }
116    }
117}
118
119impl<'a> DockerFile<'a>{
120    pub fn new() -> Self{
121        Default::default()
122    }
123
124    pub fn from_image(from: &'a str) -> Self{
125        DockerFile::new().from(from)
126    }
127
128    pub fn add(mut self,  name: &'a str, val: DockerFieldType<'a>) -> Self {
129        self.fields.push(DockerField::new(name, val));
130        self
131    }
132
133    pub fn comment(self, cmt: &'a str) -> Self{
134        self.add("#", cmt.into())
135    }
136
137    pub fn from(self, from: &'a str) -> Self {
138        self.add("FROM", from.into())
139    }
140
141    pub fn from_alias(self, alias: &'a str, from: &'a str) -> Self{
142        self.add("FROM", format!("{} as {}", from, alias).into())
143    }
144
145    pub fn run(self, from: &'a str) -> Self {
146        self.add("RUN", from.into())
147    }
148
149    pub fn cmd(self, args: &'a[&'a str]) -> Self{
150        self.add("CMD", DockerFieldType::Array(args.to_vec()))
151    }
152
153    pub fn label(self, labels: &'a[(&'a str, &'a str)])-> Self{
154        self.add("LABEL", labels.into())
155    }
156
157    pub fn expose(self, port: i32) -> Self{
158        self.add("EXPOSE", port.into())
159    }
160
161    pub fn expose_protocal(self, port:i32, prot: &'a str) -> Self{
162        self.add("EXPOSE", (port, prot).into())
163    }
164
165    pub fn env(self, vals: &'a[(&'a str, &'a str)]) -> Self{
166        self.add("ENV", vals.into())
167    }
168
169    pub fn workdir(self, dir: &'a str) -> Self{
170        self.add("WORKDIR", dir.into())
171    }
172
173    pub fn copy(self, src: &'a str, dest: &'a str) -> Self{
174        self.add("COPY", vec![src.to_string(),dest.to_string()].into())
175    }
176
177    pub fn copy_from(self, from: &'a str, src: &'a str, dest: &'a str) -> Self {
178        self.add("COPY", vec![(&["--from=", from]).join(""), src.to_string(), dest.to_string()].into())
179    }
180
181    pub fn volume(self, vols: &'a[&'a str]) -> Self{
182        self.add("VOLUME", DockerFieldType::Array(vols.to_vec()))
183    }
184
185    pub fn dockerfile(self, f: DockerFile<'a>) -> Self{
186        self.add("", f.into())
187    }
188
189    pub fn entrypoint(self, args: &'a[&'a str]) -> Self{
190        self.add("ENTRYPOINT", DockerFieldType::Array(args.to_vec()))
191    }
192
193    pub fn newline(self) -> Self{
194        self.add("", "".into())
195    }
196
197    pub fn newlines(self, ammount: i32) -> Self{
198        let mut s = self;
199        for _ in 0..ammount{
200            s = s.add("", "".into());
201        }
202        s
203    }
204
205
206
207    pub fn to_string(&self) -> String {
208        let mut out = String::new();
209
210        for f in self.fields.iter(){
211            out.push_str(f.name);
212            if !f.name.is_empty(){
213                out.push(' ');
214            }
215            out.push_str(&f.value.to_string());
216            out.push_str("\n\r");
217        }
218        out
219    }
220}