use crate::docker::config::ContainerConfig;
use crate::docker::container::ContainerHandle;
use crate::docker::error::DockerResult;
struct GroupEntry {
key: Option<String>,
handle: ContainerHandle,
}
pub struct ContainerGroup {
entries: Vec<GroupEntry>,
}
impl ContainerGroup {
pub async fn start_async(configs: Vec<ContainerConfig>) -> DockerResult<Self> {
let mut entries = Vec::with_capacity(configs.len());
for cfg in configs {
let handle = ContainerHandle::start_async(cfg).await?;
entries.push(GroupEntry { key: None, handle });
}
Ok(Self { entries })
}
#[must_use]
pub fn empty() -> Self {
Self { entries: Vec::new() }
}
pub fn insert(&mut self, key: Option<String>, handle: ContainerHandle) {
if let Some(ref k) = key {
assert!(
!self.entries.iter().any(|e| e.key.as_deref() == Some(k.as_str())),
"duplicate container key {k:?} in this group — give each container a distinct `as = \"...\"`"
);
}
self.entries.push(GroupEntry { key, handle });
}
pub fn start(configs: Vec<ContainerConfig>) -> DockerResult<Self> {
crate::block_on(Self::start_async(configs))
}
#[must_use]
pub fn container(&self, key: &str) -> Option<&ContainerHandle> {
self.entries
.iter()
.find(|e| e.key.as_deref() == Some(key) || e.handle.name() == Some(key))
.map(|e| &e.handle)
}
#[must_use]
pub fn containers(&self) -> Vec<&ContainerHandle> {
self.entries.iter().map(|e| &e.handle).collect()
}
#[must_use]
pub fn get(&self, index: usize) -> Option<&ContainerHandle> {
self.entries.get(index).map(|e| &e.handle)
}
#[must_use]
pub fn len(&self) -> usize {
self.entries.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
}
impl Drop for ContainerGroup {
fn drop(&mut self) {
}
}
impl std::fmt::Debug for ContainerGroup {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let keys: Vec<&str> = self
.entries
.iter()
.map(|e| e.key.as_deref().or_else(|| e.handle.name()).unwrap_or("<unkeyed>"))
.collect();
f.debug_struct("ContainerGroup")
.field("count", &self.entries.len())
.field("keys", &keys)
.finish()
}
}