pub type DedupKey = (String, String, String);
pub fn normalize_source(s: &str) -> String {
s.split_whitespace().collect::<Vec<_>>().join(" ")
}
pub fn dedup_key(channel: &str, peer: &str, source: &str) -> DedupKey {
(
channel.to_owned(),
peer.to_owned(),
normalize_source(source),
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn normalize_collapses_runs_of_whitespace() {
assert_eq!(normalize_source("tail -f x"), "tail -f x");
assert_eq!(normalize_source("tail -f x"), "tail -f x");
assert_eq!(normalize_source("tail\t-f\tx"), "tail -f x");
assert_eq!(normalize_source(" tail -f x "), "tail -f x");
assert_eq!(normalize_source("tail\n-f\nx"), "tail -f x");
}
#[test]
fn normalize_collapses_quoted_internal_spaces_too() {
assert_eq!(normalize_source(r#"echo "a b""#), r#"echo "a b""#);
}
#[test]
fn normalize_empty_input() {
assert_eq!(normalize_source(""), "");
assert_eq!(normalize_source(" "), "");
}
#[test]
fn dedup_key_differs_by_channel() {
let a = dedup_key("feishu", "u1", "tail -f x");
let b = dedup_key("wechat", "u1", "tail -f x");
assert_ne!(a, b);
}
#[test]
fn dedup_key_differs_by_peer() {
let a = dedup_key("feishu", "u1", "tail -f x");
let b = dedup_key("feishu", "u2", "tail -f x");
assert_ne!(a, b);
}
#[test]
fn dedup_key_normalizes_whitespace_in_source() {
let a = dedup_key("feishu", "u1", "tail -f x");
let b = dedup_key("feishu", "u1", "tail -f x");
assert_eq!(a, b);
}
}