mod render;
mod unit;
mod warnings;
use crate::compose::types::ComposeFile;
use unit::{container_unit, network_unit, volume_unit};
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive]
pub struct QuadletUnit {
pub filename: String,
pub contents: String,
}
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct QuadletOutput {
pub units: Vec<QuadletUnit>,
pub warnings: Vec<String>,
}
impl QuadletOutput {
pub fn duplicate_filename(&self) -> Option<&str> {
let mut seen = std::collections::HashSet::new();
self.units
.iter()
.find(|u| !seen.insert(u.filename.as_str()))
.map(|u| u.filename.as_str())
}
}
pub fn generate(file: &ComposeFile, project: &str) -> QuadletOutput {
let mut out = QuadletOutput::default();
for (name, cfg) in &file.networks {
if cfg.as_ref().is_some_and(|c| c.external == Some(true)) {
continue;
}
out.units.push(network_unit(name, project, cfg.as_ref()));
}
for (name, cfg) in &file.volumes {
if cfg.as_ref().is_some_and(|c| c.external == Some(true)) {
continue;
}
out.units.push(volume_unit(name, project, cfg.as_ref()));
}
let declared_volumes: Vec<&str> = file
.volumes
.iter()
.filter(|(_, cfg)| cfg.as_ref().is_none_or(|c| c.external != Some(true)))
.map(|(name, _)| name.as_str())
.collect();
let declared_networks: Vec<&str> = file
.networks
.iter()
.filter(|(_, cfg)| cfg.as_ref().is_none_or(|c| c.external != Some(true)))
.map(|(name, _)| name.as_str())
.collect();
for (name, service) in &file.services {
out.units.push(container_unit(
name,
service,
&declared_volumes,
&declared_networks,
&mut out.warnings,
));
}
out
}
#[cfg(test)]
mod tests;