hydro_test/external_client/
chat.rs1use std::hash::{DefaultHasher, Hash, Hasher};
2
3use colored::{Color, Colorize};
4use hydro_lang::live_collections::stream::NoOrder;
5use hydro_lang::location::MembershipEvent;
6use hydro_lang::nondet::NonDet;
7use hydro_lang::prelude::*;
8use hydro_std::membership::track_membership;
9use palette::{FromColor, Hsv, Srgb};
10
11fn hash_to_color<T: Hash>(input: T) -> Color {
12 let mut hasher = DefaultHasher::new();
13 input.hash(&mut hasher);
14 let hash = hasher.finish();
15
16 let hue = (hash % 360) as f32;
18 let hsv = Hsv::new(hue, 1.0, 1.0);
19 let rgb: Srgb<u8> = Srgb::from_color(hsv).into_format();
20
21 Color::TrueColor {
22 r: rgb.red,
23 g: rgb.green,
24 b: rgb.blue,
25 }
26}
27
28pub fn chat_server<'a, P>(
33 in_stream: KeyedStream<u64, String, Process<'a, P>, Unbounded>,
34 membership: KeyedStream<u64, MembershipEvent, Process<'a, P>, Unbounded>,
35 nondet_user_arrival_broadcast: NonDet,
36) -> KeyedStream<u64, String, Process<'a, P>, Unbounded, NoOrder> {
37 sliced! {
38 let msg_batch = use(in_stream, nondet_user_arrival_broadcast);
39 let members = use(track_membership(membership), nondet_user_arrival_broadcast);
40
41 let current_members = members.filter(q!(|b| *b)).keys();
42 current_members.cross_product(msg_batch.entries()).into_keyed()
43 }
44 .filter_map_with_key(q!(|(recipient_id, (sender_id, line))| {
45 if sender_id != recipient_id {
46 Some(format!(
47 "From {}: {:}",
48 sender_id,
49 line.color(self::hash_to_color(sender_id + 10))
50 ))
51 } else {
52 None
53 }
54 }))
55}