pub const KEY_PREFIX: &str = "cal";
pub const KEY_SEPARATOR: &str = ":";
pub const JAMBONZ_KEY: &str = "cal:jambonz";
pub const REGIONS_KEY: &str = "cal:regions";
pub const REGION_IDENTS_KEY: &str = "cal:region:idents";
pub const PROXIES_KEY: &str = "cal:proxies";
pub const WS_CONNECTIONS_KEY: &str = "cal:ws:connections";
pub const GLOBAL_EVENTS_CHANNEL: &str = "cal:events";
pub const ACCOUNTS_KEY: &str = "cal:accounts";
pub const ACCOUNT_IDENTS_KEY: &str = "cal:account:idents";
pub const USERS_KEY: &str = "cal:users";
pub const USER_IDENTS_KEY: &str = "cal:user:idents";
#[inline]
pub fn build_key(components: &[&str]) -> String {
let mut key = String::with_capacity(128);
key.push_str(KEY_PREFIX);
for component in components {
key.push_str(KEY_SEPARATOR);
key.push_str(component);
}
key
}
#[inline]
pub fn build_account_key(account_id: &str, components: &[&str]) -> String {
let mut parts = vec!["account", account_id];
parts.extend_from_slice(components);
build_key(&parts)
}
#[inline]
pub fn build_trunk_key(trunk_ip: &str) -> String {
build_key(&["trunk", trunk_ip])
}
pub struct AccountKeys;
impl AccountKeys {
pub fn devices(account_id: &str) -> String {
build_account_key(account_id, &["devices"])
}
pub fn device_idents(account_id: &str) -> String {
build_account_key(account_id, &["device", "idents"])
}
pub fn ddis(account_id: &str) -> String {
build_account_key(account_id, &["ddis"])
}
pub fn trunks(account_id: &str) -> String {
build_account_key(account_id, &["trunks"])
}
pub fn hooks(account_id: &str) -> String {
build_account_key(account_id, &["hooks"])
}
pub fn assets(account_id: &str) -> String {
build_account_key(account_id, &["assets"])
}
pub fn addresses(account_id: &str) -> String {
build_account_key(account_id, &["addresses"])
}
pub fn contacts(account_id: &str) -> String {
build_account_key(account_id, &["contacts"])
}
pub fn contact_idents(account_id: &str) -> String {
build_account_key(account_id, &["contact", "idents"])
}
}
pub struct AgentKeys;
impl AgentKeys {
pub fn status(account_id: &str, user_id: &str) -> String {
build_account_key(account_id, &["agent", "status", user_id])
}
pub fn by_user(account_id: &str) -> String {
build_account_key(account_id, &["agents", "by_user"])
}
pub fn registered(account_id: &str) -> String {
build_account_key(account_id, &["agents", "registered"])
}
pub fn available(account_id: &str) -> String {
build_account_key(account_id, &["agents", "available"])
}
pub fn connected(account_id: &str) -> String {
build_account_key(account_id, &["agents", "connected"])
}
}
pub struct SessionKeys;
impl SessionKeys {
pub fn session(account_id: &str, session_id: &str) -> String {
build_account_key(account_id, &["session", session_id])
}
pub fn active(account_id: &str) -> String {
build_account_key(account_id, &["sessions", "active"])
}
}
pub struct QueueKeys;
impl QueueKeys {
pub fn queue(account_id: &str, queue_name: &str) -> String {
build_account_key(account_id, &["queue", queue_name])
}
pub fn metadata(account_id: &str) -> String {
build_account_key(account_id, &["queues", "meta"])
}
pub fn active(account_id: &str) -> String {
build_account_key(account_id, &["queues", "active"])
}
}
pub struct ConversationKeys;
impl ConversationKeys {
pub fn conversation(account_id: &str, conversation_id: &str) -> String {
build_account_key(account_id, &["conversation", conversation_id])
}
pub fn active(account_id: &str) -> String {
build_account_key(account_id, &["conversations", "active"])
}
pub fn by_phone(account_id: &str) -> String {
build_account_key(account_id, &["conversations", "by_phone"])
}
}
pub struct ChannelKeys;
impl ChannelKeys {
pub fn account_events(account_id: &str) -> String {
build_account_key(account_id, &["events"])
}
pub fn agent_events(account_id: &str, user_id: &str) -> String {
build_account_key(account_id, &["agent", user_id, "events"])
}
}
pub fn extract_account_id(key: &str) -> Option<&str> {
let parts: Vec<&str> = key.split(KEY_SEPARATOR).collect();
if parts.len() >= 3 && parts[0] == KEY_PREFIX && parts[1] == "account" {
Some(parts[2])
} else {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_build_key() {
assert_eq!(build_key(&["test", "key"]), "cal:test:key");
}
#[test]
fn test_build_account_key() {
assert_eq!(
build_account_key("123", &["devices"]),
"cal:account:123:devices"
);
}
#[test]
fn test_extract_account_id() {
assert_eq!(
extract_account_id("cal:account:123:devices"),
Some("123")
);
assert_eq!(
extract_account_id("cal:regions"),
None
);
}
}