use crate::config::schema::CosmosConfig;
#[derive(Debug, Clone, PartialEq)]
pub struct ContainerSpec {
pub name: String,
pub partition_key: String,
}
pub fn desired_containers(cosmos: &CosmosConfig) -> Vec<ContainerSpec> {
let layout = &cosmos.containers;
let mut out = vec![];
for (name_opt, partition_key) in [
(layout.jira_issues.as_deref(), "/id"),
(layout.jira_sprints.as_deref(), "/id"),
(layout.jira_fix_versions.as_deref(), "/id"),
(layout.jira_projects.as_deref(), "/id"),
(layout.confluence_pages.as_deref(), "/id"),
(layout.confluence_spaces.as_deref(), "/id"),
] {
if let Some(n) = name_opt {
out.push(ContainerSpec {
name: n.to_string(),
partition_key: partition_key.to_string(),
});
}
}
out.push(ContainerSpec {
name: cosmos.meta_container.clone(),
partition_key: "/source_name".to_string(),
});
out
}
#[derive(Debug, Clone, PartialEq)]
pub enum ContainerDiff {
Create(ContainerSpec),
Match {
name: String,
},
PartitionKeyMismatch {
name: String,
want: String,
have: String,
},
}
pub fn diff_containers(want: &[ContainerSpec], have: &[ContainerSpec]) -> Vec<ContainerDiff> {
let mut out = vec![];
for w in want {
match have.iter().find(|h| h.name == w.name) {
Some(h) if h.partition_key == w.partition_key => {
out.push(ContainerDiff::Match {
name: w.name.clone(),
});
}
Some(h) => out.push(ContainerDiff::PartitionKeyMismatch {
name: w.name.clone(),
want: w.partition_key.clone(),
have: h.partition_key.clone(),
}),
None => out.push(ContainerDiff::Create(w.clone())),
}
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn diff_creates_missing_and_matches_existing() {
let want = vec![
ContainerSpec {
name: "a".into(),
partition_key: "/id".into(),
},
ContainerSpec {
name: "b".into(),
partition_key: "/id".into(),
},
];
let have = vec![ContainerSpec {
name: "a".into(),
partition_key: "/id".into(),
}];
assert_eq!(
diff_containers(&want, &have),
vec![
ContainerDiff::Match { name: "a".into() },
ContainerDiff::Create(ContainerSpec {
name: "b".into(),
partition_key: "/id".into()
}),
]
);
}
#[test]
fn diff_flags_partition_key_mismatch() {
let want = vec![ContainerSpec {
name: "a".into(),
partition_key: "/id".into(),
}];
let have = vec![ContainerSpec {
name: "a".into(),
partition_key: "/wrong".into(),
}];
assert_eq!(
diff_containers(&want, &have),
vec![ContainerDiff::PartitionKeyMismatch {
name: "a".into(),
want: "/id".into(),
have: "/wrong".into(),
}]
);
}
}