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)
}
}