use futures::{Stream, StreamExt}; use redis::RedisError; use url::Url; #[derive(Clone)] pub struct FirehoseFactory { redis_url: Url, } impl FirehoseFactory { #[must_use] pub fn new(redis_url: String, redis_password_file: String) -> Self { let redis_password = std::fs::read_to_string(redis_password_file) .expect("redis_password_file"); let mut redis_url = Url::parse(&redis_url) .expect("redis_url"); redis_url.set_password(Some(&redis_password)).unwrap(); FirehoseFactory { redis_url } } pub async fn produce(&self) -> Result, Vec)>, RedisError> { let client = redis::Client::open(self.redis_url.clone())?; let mut pubsub_conn = client.get_async_connection() .await? .into_pubsub(); pubsub_conn.subscribe("firehose") .await?; let stream = pubsub_conn.into_on_message() .filter_map(|msg| async move { let data = msg.get_payload::>().ok()?; let nul_pos = data.iter().position(|&b| b == 0)?; let event_type = data[..nul_pos].to_owned(); let post_data: Vec = data[nul_pos + 1..].to_owned(); Some((event_type, post_data)) }); Ok(stream) } }