chat_core/
room.rs

1use sha2::{Digest, Sha256};
2use petname::Generator;
3
4const TOPIC_PREFIX: &str = "libp2p-gossipsub-manager:v1:";
5
6pub fn hash_topic(room_name: &str) -> String {
7    let input = format!("{}{}", TOPIC_PREFIX, room_name);
8    let mut hasher = Sha256::new();
9    hasher.update(input.as_bytes());
10    let result = hasher.finalize();
11    hex::encode(result)
12}
13
14pub fn generate_random_nickname() -> String {
15    use petname::Petnames;
16    let petnames = Petnames::default();
17    petnames.generate_one(2, "-").unwrap_or_else(|| "unknown-user".into())
18}
19
20#[cfg(test)]
21mod tests {
22    use super::*;
23
24    #[test]
25    fn hash_topic_returns_64_char_hex() {
26        let result = hash_topic("test-room");
27        assert!(result.chars().all(|c| c.is_ascii_hexdigit()));
28        assert_eq!(result.len(), 64);
29        assert_eq!(result, result.to_lowercase());
30    }
31
32    #[test]
33    fn hash_topic_is_deterministic() {
34        let r1 = hash_topic("my-room");
35        let r2 = hash_topic("my-room");
36        assert_eq!(r1, r2);
37    }
38
39    #[test]
40    fn hash_topic_differs_for_different_rooms() {
41        let r1 = hash_topic("room-a");
42        let r2 = hash_topic("room-b");
43        assert_ne!(r1, r2);
44    }
45
46    #[test]
47    fn hash_topic_uses_v1_prefix() {
48        let v1 = hash_topic("foo");
49        let v3_legacy = {
50            let input = format!("libp2p-chat-topic:v3:{}", "foo");
51            let mut hasher = Sha256::new();
52            hasher.update(input.as_bytes());
53            let result = hasher.finalize();
54            hex::encode(result)
55        };
56        assert_ne!(v1, v3_legacy);
57    }
58
59    #[test]
60    fn generate_random_nickname_is_non_empty() {
61        let name = generate_random_nickname();
62        assert!(!name.is_empty());
63    }
64
65    #[test]
66    fn generate_random_nickname_is_hyphenated_lowercase() {
67        let name = generate_random_nickname();
68        assert!(name.chars().all(|c| c.is_ascii_lowercase() || c == '-'));
69        assert!(name.contains('-'));
70    }
71
72    #[test]
73    fn generate_random_nickname_returns_different_names() {
74        let name1 = generate_random_nickname();
75        let name2 = generate_random_nickname();
76        assert_ne!(name1, name2);
77    }
78}