use std::collections::HashMap;
use crate::{
composition::{Composition, StaticManagementPolicy},
waitfor::WaitFor,
Image, LogOptions, StartPolicy,
};
mod private {
pub use super::*;
pub trait Sealed {}
impl Sealed for TestBodySpecification {}
impl Sealed for TestSuiteSpecification {}
impl Sealed for DynamicSpecification {}
impl Sealed for ExternalSpecification {}
}
pub trait ContainerSpecification: private::Sealed {
fn into_composition(self) -> Composition;
}
macro_rules! impl_specify_container {
($s:ty) => {
impl $s {
pub fn set_start_policy(self, start_policy: StartPolicy) -> Self {
Self {
composition: self.composition.with_start_policy(start_policy),
}
}
pub fn replace_env(self, env: HashMap<String, String>) -> Self {
Self {
composition: self.composition.with_env(env),
}
}
pub fn modify_env<T: ToString, S: ToString>(&mut self, name: T, value: S) -> &mut Self {
self.composition.env(name, value);
self
}
pub fn replace_cmd(self, cmd: Vec<String>) -> Self {
Self {
composition: self.composition.with_cmd(cmd),
}
}
#[cfg(target_os = "linux")]
pub fn tmpfs<T: ToString>(&mut self, path: T) -> &mut Self {
self.composition.tmpfs(path.to_string());
self
}
#[cfg(target_os = "linux")]
pub fn replace_tmpfs(self, paths: Vec<String>) -> Self {
Self {
composition: self.composition.with_tmpfs(paths),
}
}
pub fn append_cmd<T: ToString>(&mut self, cmd: T) -> &mut Self {
self.composition.cmd(cmd);
self
}
pub fn set_publish_all_ports(mut self, publish: bool) -> Self {
self.composition.publish_all_ports(publish);
self
}
pub fn modify_port_map(&mut self, exported: u32, host: u32) -> &mut Self {
self.composition.port_map(exported, host);
self
}
pub fn privileged(&mut self, privileged: bool) -> &mut Self {
self.composition.privileged = privileged;
self
}
pub fn set_privileged(mut self, privileged: bool) -> Self {
self.composition.privileged = privileged;
self
}
pub fn set_handle<T: ToString>(self, handle: T) -> Self {
Self {
composition: self.composition.with_container_name(handle),
}
}
pub fn replace_network_alias(self, aliases: Vec<String>) -> Self {
Self {
composition: self.composition.with_alias(aliases),
}
}
pub fn append_network_alias(&mut self, alias: String) -> &mut Self {
self.composition.alias(alias);
self
}
pub fn set_wait_for(self, wait: Box<dyn WaitFor>) -> Self {
Self {
composition: self.composition.with_wait_for(wait),
}
}
pub fn set_log_options(self, log_options: Option<LogOptions>) -> Self {
Self {
composition: self.composition.with_log_options(log_options),
}
}
pub fn modify_named_volume<T: ToString, S: ToString>(
&mut self,
volume_name: T,
path_in_container: S,
) -> &mut Self {
self.composition
.named_volume(volume_name, path_in_container);
self
}
pub fn modify_bind_mount<T: ToString, S: ToString>(
&mut self,
host_path: T,
path_in_container: S,
) -> &mut Self {
self.composition.bind_mount(host_path, path_in_container);
self
}
pub fn inject_container_name<T: ToString, E: ToString>(
&mut self,
handle: T,
env: E,
) -> &mut Self {
self.composition.inject_container_name(handle, env);
self
}
}
};
}
#[derive(Clone, Debug)]
pub struct ExternalSpecification {
name: String,
}
impl ExternalSpecification {
pub fn with_container_name<T: ToString>(name: T) -> Self {
Self {
name: name.to_string(),
}
}
}
impl ContainerSpecification for ExternalSpecification {
fn into_composition(self) -> Composition {
let mut c = Composition::with_repository("NOT REQUIRED").with_container_name(self.name);
c.static_container(StaticManagementPolicy::External);
c
}
}
#[derive(Clone, Debug)]
pub struct TestSuiteSpecification {
composition: Composition,
}
impl ContainerSpecification for TestSuiteSpecification {
fn into_composition(mut self) -> Composition {
self.composition
.static_container(StaticManagementPolicy::Internal);
self.composition
}
}
impl TestSuiteSpecification {
pub fn with_repository<T: ToString>(repository: T) -> Self {
Self {
composition: Composition::with_repository(repository),
}
}
pub fn with_image(image: Image) -> Self {
Self {
composition: Composition::with_image(image),
}
}
}
impl_specify_container!(TestSuiteSpecification);
pub struct TestBodySpecification {
composition: Composition,
}
impl ContainerSpecification for TestBodySpecification {
fn into_composition(self) -> Composition {
self.composition
}
}
impl TestBodySpecification {
pub fn with_repository<T: ToString>(repository: T) -> Self {
Self {
composition: Composition::with_repository(repository),
}
}
pub fn with_image(image: Image) -> Self {
Self {
composition: Composition::with_image(image),
}
}
}
impl_specify_container!(TestBodySpecification);
#[derive(Clone, Debug)]
pub struct DynamicSpecification {
composition: Composition,
}
impl ContainerSpecification for DynamicSpecification {
fn into_composition(mut self) -> Composition {
self.composition
.static_container(StaticManagementPolicy::Dynamic);
self.composition
}
}
impl DynamicSpecification {
pub fn with_repository<T: ToString, S: ToString>(repository: T, container_name: S) -> Self {
Self {
composition: Composition::with_repository(repository)
.with_container_name(container_name),
}
}
pub fn with_image<S: ToString>(image: Image, container_name: S) -> Self {
Self {
composition: Composition::with_image(image).with_container_name(container_name),
}
}
}
impl_specify_container!(DynamicSpecification);