pub struct ComposeInfo {
pub project: String,
pub service: String,
}
pub fn extract_compose_info(
labels: &serde_json::Map<String, serde_json::Value>,
) -> Option<ComposeInfo> {
let project = labels
.get("com.docker.compose.project")?
.as_str()
.filter(|s| !s.is_empty())?;
let service = labels
.get("com.docker.compose.service")?
.as_str()
.filter(|s| !s.is_empty())?;
Some(ComposeInfo {
project: project.to_string(),
service: service.to_string(),
})
}
pub fn collect_aliases(container_name: &str, compose: Option<&ComposeInfo>) -> Vec<String> {
if container_name.is_empty() {
return vec![];
}
match compose {
Some(info) => {
let service_alias = format!("{}.{}", info.service, info.project);
vec![service_alias, container_name.to_string()]
}
None => vec![container_name.to_string()],
}
}
#[cfg(test)]
mod tests {
use super::*;
fn compose(project: &str, service: &str) -> ComposeInfo {
ComposeInfo {
project: project.to_string(),
service: service.to_string(),
}
}
#[test]
fn compose_container_aliases() {
let info = compose("myproject", "web");
let aliases = collect_aliases("myproject-web-1", Some(&info));
assert_eq!(aliases, vec!["web.myproject", "myproject-web-1"]);
}
#[test]
fn compose_multi_segment_service() {
let info = compose("myproject", "api-server");
let aliases = collect_aliases("myproject-api-server-2", Some(&info));
assert_eq!(
aliases,
vec!["api-server.myproject", "myproject-api-server-2"]
);
}
#[test]
fn compose_v1_underscore() {
let info = compose("myproject", "web");
let aliases = collect_aliases("myproject_web_1", Some(&info));
assert_eq!(aliases, vec!["web.myproject", "myproject_web_1"]);
}
#[test]
fn plain_container_no_compose() {
let aliases = collect_aliases("mycontainer", None);
assert_eq!(aliases, vec!["mycontainer"]);
}
#[test]
fn empty_name() {
let aliases = collect_aliases("", None);
assert!(aliases.is_empty());
}
#[test]
fn extract_compose_info_from_labels() {
let mut labels = serde_json::Map::new();
labels.insert(
"com.docker.compose.project".to_string(),
serde_json::Value::String("myproject".to_string()),
);
labels.insert(
"com.docker.compose.service".to_string(),
serde_json::Value::String("web".to_string()),
);
let info = extract_compose_info(&labels).unwrap();
assert_eq!(info.project, "myproject");
assert_eq!(info.service, "web");
}
#[test]
fn extract_compose_info_missing_labels() {
let labels = serde_json::Map::new();
assert!(extract_compose_info(&labels).is_none());
}
#[test]
fn extract_compose_info_empty_values() {
let mut labels = serde_json::Map::new();
labels.insert(
"com.docker.compose.project".to_string(),
serde_json::Value::String(String::new()),
);
labels.insert(
"com.docker.compose.service".to_string(),
serde_json::Value::String("web".to_string()),
);
assert!(extract_compose_info(&labels).is_none());
}
}