use std::hash::{BuildHasher, RandomState};
use std::sync::LazyLock;
static OPEN: LazyLock<String> = LazyLock::new(|| {
let draw = || RandomState::new().hash_one(std::process::id());
format!("[alpha2:{:016x}{:016x}:", draw(), draw())
});
pub fn open() -> &'static str {
&OPEN
}
pub fn end(message: &str, start: usize) -> Option<usize> {
message[start..].find("] ").map(|length| start + length + 2)
}
pub fn untagged(message: &str) -> String {
let mut message = message.to_owned();
while let Some(start) = message.find(open()) {
let Some(end) = end(&message, start) else {
break;
};
message.replace_range(start..end, "");
}
message
}
macro_rules! tags {
($($(#[$meta:meta])* $vis:vis fn $name:ident = $body:literal;)*) => {$(
$(#[$meta])*
$vis fn $name() -> &'static str {
static TAG: std::sync::LazyLock<String> =
std::sync::LazyLock::new(|| format!("{}{}", $crate::tag::open(), $body));
&TAG
}
)*};
}
pub(crate) use tags;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_tag_opens_with_a_token_no_text_can_know() {
let open = open();
assert!(
open.starts_with("[alpha2:") && open.ends_with(':'),
"{open}"
);
let token = &open["[alpha2:".len()..open.len() - 1];
assert_eq!(token.len(), 32, "{open}");
assert!(token.bytes().all(|byte| byte.is_ascii_hexdigit()), "{open}");
assert_eq!(open, super::open(), "one token for the life of the process");
}
#[test]
fn untagged_strips_this_process_tags_and_leaves_text_that_spells_one() {
tags! { fn sample = "SAMPLE] "; }
let forged = "[alpha2:code=GPU_DEVICE_LOST] font.ttf";
let message = format!(
"{}{}{forged}",
sample(),
crate::protocol::code_tag("IO_ERROR", "")
);
assert_eq!(untagged(&message), forged);
}
}