use std::borrow::Cow;
const MARKER: &str = "mk--";
fn is_valid_comms_component(s: &str) -> bool {
let mut chars = s.chars();
let Some(first) = chars.next() else {
return false;
};
if !first.is_ascii_alphabetic() && first != '_' {
return false;
}
chars.all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_')
}
fn escape_body(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 8);
for c in s.chars() {
match c {
'_' => out.push_str("__"),
':' => out.push_str("_c"),
c if c.is_ascii_alphanumeric() || c == '-' => out.push(c),
c => {
out.push_str("_x");
out.push_str(&format!("{:x}", c as u32));
out.push('_');
}
}
}
out
}
fn unescape_body(s: &str) -> Option<String> {
let mut out = String::with_capacity(s.len());
let mut chars = s.chars();
while let Some(c) = chars.next() {
if c != '_' {
out.push(c);
continue;
}
match chars.next()? {
'_' => out.push('_'),
'c' => out.push(':'),
'x' => {
let mut hex = String::new();
loop {
match chars.next()? {
'_' => break,
h => hex.push(h),
}
}
let code = u32::from_str_radix(&hex, 16).ok()?;
out.push(char::from_u32(code)?);
}
_ => return None,
}
}
Some(out)
}
pub fn mob_member_id_str(alias: &str) -> Cow<'_, str> {
if is_valid_comms_component(alias) && !alias.starts_with(MARKER) {
Cow::Borrowed(alias)
} else {
Cow::Owned(format!("{MARKER}{}", escape_body(alias)))
}
}
pub fn mob_member_id(alias: &str) -> meerkat_mob::ids::AgentIdentity {
meerkat_mob::ids::AgentIdentity::from(mob_member_id_str(alias).as_ref())
}
pub fn runtime_alias_str(member_id: &str) -> Cow<'_, str> {
match member_id.strip_prefix(MARKER) {
Some(body) => match unescape_body(body) {
Some(alias) => Cow::Owned(alias),
None => Cow::Borrowed(member_id),
},
None => Cow::Borrowed(member_id),
}
}
pub fn runtime_event_alias(runtime_id: &meerkat_mob::ids::AgentRuntimeId) -> String {
format!(
"{}:{}",
runtime_alias_str(runtime_id.identity.as_str()),
runtime_id.generation.get()
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn plain_member_names_pass_through_unchanged() {
for name in ["worker", "worker-one", "_internal", "Agent7"] {
assert_eq!(mob_member_id_str(name), name);
assert_eq!(runtime_alias_str(name), name);
}
}
#[test]
fn colon_aliases_round_trip_and_are_comms_safe() {
for alias in [
"rt:review:singleton:0",
"rt:channel:C0SMOKEOB3:0",
"agent:beta",
"review:singleton",
"rt:agent-x:0",
"with_underscore:and:colons",
] {
let encoded = mob_member_id_str(alias);
assert!(
is_valid_comms_component(&encoded),
"{encoded:?} must satisfy meerkat 0.7 MemberCommsName"
);
assert_eq!(runtime_alias_str(&encoded), alias, "round trip of {alias}");
}
}
#[test]
fn non_ascii_and_punctuation_round_trip() {
for alias in ["user@host", "a.b:c", "9starts-with-digit", "ünïcode:1"] {
let encoded = mob_member_id_str(alias);
assert!(is_valid_comms_component(&encoded), "{encoded:?}");
assert_eq!(runtime_alias_str(&encoded), alias);
}
}
#[test]
fn reserved_marker_names_re_encode_so_round_trip_holds() {
let alias = "mk--rt_creview";
let encoded = mob_member_id_str(alias);
assert_ne!(encoded, alias, "marker-prefixed names must be re-encoded");
assert_eq!(runtime_alias_str(&encoded), alias);
}
#[test]
fn runtime_event_alias_decodes_encoded_roster_member_ids() {
use meerkat_mob::ids::{AgentIdentity, AgentRuntimeId, Generation};
let encoded = mob_member_id_str("rt:review:singleton:0").into_owned();
let runtime_id =
AgentRuntimeId::new(AgentIdentity::from(encoded.as_str()), Generation::new(1));
assert_eq!(runtime_event_alias(&runtime_id), "rt:review:singleton:0:1");
let runtime_id = AgentRuntimeId::initial(AgentIdentity::from("worker-one"));
assert_eq!(runtime_event_alias(&runtime_id), "worker-one:0");
}
#[test]
fn encoding_is_injective_across_pass_through_and_encoded_forms() {
let inputs = [
"rt:review:singleton:0",
"rt-review-singleton-0",
"rt_creview_csingleton_c0",
"mk--rt_creview_csingleton_c0",
];
let mut seen = std::collections::BTreeSet::new();
for input in inputs {
assert!(
seen.insert(mob_member_id_str(input).into_owned()),
"collision on {input}"
);
}
}
fn defensive_corpus() -> Vec<String> {
let mut v: Vec<String> = [
"worker",
"worker-one",
"_internal",
"Agent7",
"a",
"identity:parent-1",
"identity:parent-2",
"identity:child-1",
"identity:child-2",
"domain:calendar",
"domain:school",
"domain:health",
"domain:home",
"domain:home-automation",
"domain:finance",
"domain:discovery",
"family-group:main",
"triage:main",
"gate:main",
"rt:identity:parent-1:0",
"rt:domain:home-automation:3",
"rt:channel:C0SMOKEOB3:0",
"rt:review:singleton:12",
"a:b_c",
"with_underscore:and:colons",
"user@host",
"a.b:c",
"9starts-with-digit",
"::",
":",
"-",
"mk--collision",
]
.into_iter()
.map(String::from)
.collect();
v.push("ünïcode:1".to_string());
v.push("emoji-😀:2".to_string());
v.push("Ω≈ç:3".to_string());
v.push("tab\tnl\n".to_string());
v.push("\u{0}\u{1f}x".to_string());
v.push("a b".to_string());
v.push(String::new());
v
}
#[test]
fn homecore_corpus_round_trips_and_is_comms_safe() {
for alias in defensive_corpus() {
let encoded = mob_member_id_str(&alias).into_owned();
assert!(
is_valid_comms_component(&encoded),
"encoded {encoded:?} (from {alias:?}) is not a valid comms component"
);
assert!(
!encoded.contains([':', '/']),
"encoded {encoded:?} leaks a routing separator"
);
assert_eq!(
runtime_alias_str(&encoded),
alias,
"round trip of {alias:?}"
);
}
}
#[test]
fn encoded_ids_satisfy_meerkat_member_comms_name_validator() {
use meerkat_core::connection::MemberCommsName;
for alias in defensive_corpus() {
let encoded = mob_member_id_str(&alias).into_owned();
assert!(
MemberCommsName::new("homecore-mob", "worker", encoded.clone()).is_ok(),
"MemberCommsName::new rejected encoded id {encoded:?} (from alias {alias:?})"
);
}
}
#[test]
fn exact_wire_format_for_known_aliases() {
let cases = [
("worker-one", "worker-one"), ("identity:parent-1", "mk--identity_cparent-1"),
("domain:home-automation", "mk--domain_chome-automation"),
("family-group:main", "mk--family-group_cmain"),
("rt:identity:parent-1:0", "mk--rt_cidentity_cparent-1_c0"),
("triage:main", "mk--triage_cmain"),
("a:b_c", "mk--a_cb__c"),
("a b", "mk--a_x20_b"),
("", "mk--"),
];
for (alias, expected) in cases {
assert_eq!(mob_member_id_str(alias), expected, "encode {alias:?}");
assert_eq!(runtime_alias_str(expected), alias, "decode {expected:?}");
}
}
#[test]
fn malformed_encoded_bodies_decode_to_literal_without_panic() {
for bad in [
"mk--_", "mk--_z", "mk--_x", "mk--_x_", "mk--_xZZ_", "mk--_x110000_", "mk--_xffffffff_", "mk--abc_", ] {
assert_eq!(runtime_alias_str(bad), bad, "literal fallback for {bad:?}");
}
}
#[test]
fn empty_and_boundary_strings_round_trip() {
assert_eq!(mob_member_id_str(""), "mk--");
assert_eq!(runtime_alias_str("mk--"), "");
for alias in [":", "_", "-", "::", "_x", "mk", "mk-", "mk--"] {
let encoded = mob_member_id_str(alias).into_owned();
assert!(
is_valid_comms_component(&encoded),
"{encoded:?} not comms-safe"
);
assert_eq!(runtime_alias_str(&encoded), alias, "round trip {alias:?}");
}
}
#[test]
fn decode_then_encode_canonicalizes_both_id_spaces() {
for (input, canonical) in [
("rt:domain:home:0", "mk--rt_cdomain_chome_c0"),
("mk--rt_cdomain_chome_c0", "mk--rt_cdomain_chome_c0"),
("domain:home", "mk--domain_chome"),
("mk--domain_chome", "mk--domain_chome"),
("digest-owner", "digest-owner"),
] {
let key = mob_member_id_str(runtime_alias_str(input).as_ref()).into_owned();
assert_eq!(key, canonical, "canonical roster key for {input:?}");
}
assert_ne!(
mob_member_id_str("mk--rt_cdomain_chome_c0"),
"mk--rt_cdomain_chome_c0",
"encode alone re-encodes roster ids — never use it on binding member ids"
);
}
#[test]
fn decode_is_identity_on_unencoded_ids() {
for id in [
"worker",
"worker-one",
"_internal",
"Agent7",
"rt-review-singleton-0",
"a_cb", ] {
assert_eq!(runtime_alias_str(id), id);
}
}
#[test]
fn runtime_event_alias_across_generations_and_forms() {
use meerkat_mob::ids::{AgentIdentity, AgentRuntimeId, Generation};
let encoded = mob_member_id_str("rt:identity:parent-1:0").into_owned();
let rid = AgentRuntimeId::new(AgentIdentity::from(encoded.as_str()), Generation::new(7));
assert_eq!(runtime_event_alias(&rid), "rt:identity:parent-1:0:7");
let encoded = mob_member_id_str("domain:home-automation").into_owned();
let rid = AgentRuntimeId::new(AgentIdentity::from(encoded.as_str()), Generation::new(1));
assert_eq!(runtime_event_alias(&rid), "domain:home-automation:1");
let rid = AgentRuntimeId::initial(AgentIdentity::from("triage-main"));
assert_eq!(runtime_event_alias(&rid), "triage-main:0");
}
#[test]
fn round_trip_is_total_and_injective_over_generated_corpus() {
use meerkat_core::connection::MemberCommsName;
use std::collections::BTreeMap;
let charset = ['a', 'Z', '0', '-', '_', ':', '.', '@', ' ', 'ü', '😀'];
let mut aliases: Vec<String> = vec![String::new()];
let mut frontier = vec![String::new()];
for _ in 0..3 {
let mut next = Vec::new();
for prefix in &frontier {
for c in charset {
let mut s = prefix.clone();
s.push(c);
aliases.push(s.clone());
next.push(s);
}
}
frontier = next;
}
let mut encoded_to_alias: BTreeMap<String, String> = BTreeMap::new();
for alias in &aliases {
let encoded = mob_member_id_str(alias).into_owned();
assert!(
MemberCommsName::new("m", "r", encoded.clone()).is_ok(),
"encoded {encoded:?} (from {alias:?}) is not comms-safe"
);
assert_eq!(
&runtime_alias_str(&encoded).into_owned(),
alias,
"round trip of {alias:?}"
);
if let Some(prev) = encoded_to_alias.insert(encoded.clone(), alias.clone()) {
assert_eq!(
&prev, alias,
"collision: {prev:?} and {alias:?} both encode to {encoded:?}"
);
}
}
}
}