use serde::{Deserialize, Serialize};
use crate::ir::IrError;
use crate::ir::cluster::role::Role;
use crate::ir::cluster::tablespace::Tablespace;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
pub struct ClusterCatalog {
pub roles: Vec<Role>,
pub tablespaces: Vec<Tablespace>,
}
impl ClusterCatalog {
#[must_use]
pub const fn empty() -> Self {
Self {
roles: Vec::new(),
tablespaces: Vec::new(),
}
}
pub fn canonicalize(&mut self) -> Result<(), IrError> {
crate::ir::canon::cluster::run(self)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::identifier::Identifier;
use crate::ir::cluster::role::{Role, RoleAttributes};
fn id(s: &str) -> Identifier {
Identifier::from_unquoted(s).unwrap()
}
fn role(name: &str) -> Role {
Role {
name: id(name),
attributes: RoleAttributes::default(),
member_of: vec![],
comment: None,
}
}
#[test]
fn empty_catalog_canonicalizes_idempotently() {
let mut c = ClusterCatalog::empty();
c.canonicalize().unwrap();
c.canonicalize().unwrap();
assert!(c.roles.is_empty());
}
#[test]
fn canonicalize_sorts_roles_by_name() {
let mut c = ClusterCatalog {
roles: vec![role("zebra"), role("alpha"), role("middle")],
tablespaces: vec![],
};
c.canonicalize().unwrap();
let names: Vec<_> = c.roles.iter().map(|r| r.name.as_str().to_owned()).collect();
assert_eq!(names, vec!["alpha", "middle", "zebra"]);
}
}