use origin_domain::{AccountId, ConnectorId};
pub fn platform(area: &str) -> String {
format!("origin.{area}")
}
pub fn account(connector: &ConnectorId, account: &AccountId, area: &str) -> String {
format!("acct.{connector}.{account}.{area}")
}
pub fn account_prefix(connector: &ConnectorId, account: &AccountId) -> String {
format!("acct.{connector}.{account}.")
}
pub fn module(module: &str, area: &str) -> String {
format!("app.{module}.{area}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn an_account_prefix_covers_its_namespaces() {
let connector = ConnectorId::new("github");
let id = AccountId::new("a1b2");
let prefix = account_prefix(&connector, &id);
assert!(account(&connector, &id, "notifications").starts_with(&prefix));
assert!(account(&connector, &id, "sync").starts_with(&prefix));
}
#[test]
fn a_prefix_cannot_match_a_longer_account_id() {
let connector = ConnectorId::new("github");
let prefix = account_prefix(&connector, &AccountId::new("a1"));
let other = account(&connector, &AccountId::new("a1b2"), "sync");
assert!(
!other.starts_with(&prefix),
"the trailing separator is what prevents this: {prefix} vs {other}"
);
}
#[test]
fn platform_and_product_namespaces_never_collide_with_account_data() {
assert!(!platform("settings").starts_with("acct."));
assert!(!module("planning", "templates").starts_with("acct."));
}
}