use sha2::{Digest, Sha256};
pub(crate) fn content_hash8(content: &str) -> String {
let digest = Sha256::digest(content.as_bytes());
digest[..4]
.iter()
.map(|b| format!("{b:02x}"))
.collect::<Vec<_>>()
.join("")
}
#[allow(clippy::too_many_arguments)] pub(crate) fn log_send_success(
origin: &str,
origin_detail: &str,
session: &str,
kind: &str,
path: &str,
chat_id: i64,
thread_id: Option<i32>,
msg_id: i32,
len: usize,
hash8: &str,
) {
tracing::info!(
"Telegram send ok: origin={origin} detail={origin_detail} session={session} \
kind={kind} path={path} chat={chat_id} thread={thread_id:?} msg={msg_id} len={len} \
hash8={hash8}"
);
}
#[allow(clippy::too_many_arguments)] pub(crate) fn log_send_failure(
origin: &str,
origin_detail: &str,
session: &str,
kind: &str,
path: &str,
chat_id: i64,
thread_id: Option<i32>,
len: usize,
hash8: &str,
error: &str,
) {
tracing::warn!(
"Telegram send failed: origin={origin} detail={origin_detail} session={session} \
kind={kind} path={path} chat={chat_id} thread={thread_id:?} len={len} hash8={hash8} \
error={error}"
);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hash8_is_stable_and_8_hex_chars() {
let a = content_hash8("hello world");
let b = content_hash8("hello world");
assert_eq!(a, b);
assert_eq!(a.len(), 8);
assert!(a.chars().all(|c| c.is_ascii_hexdigit()));
}
#[test]
fn hash8_separates_different_content() {
assert_ne!(content_hash8("hello world"), content_hash8("hello worlD"));
}
#[test]
fn hash8_handles_empty_and_multibyte() {
assert_eq!(content_hash8("").len(), 8);
assert_eq!(content_hash8("ção 🦀 açúcar").len(), 8);
}
}