flippico_cache/types/
channels.rs

1use redis::{FromRedisValue, RedisResult, ToRedisArgs, Value};
2use serde::{Deserialize, Serialize};
3
4#[derive(Serialize, PartialEq, Debug, Deserialize)]
5pub enum SubscriptionChannel {
6    Amadeus,
7    Notifica,
8    BajkomatApi,
9}
10
11impl SubscriptionChannel {
12    pub fn get_channel(&self) -> &'static str {
13        match self {
14            SubscriptionChannel::Amadeus => "AMADEUS_CHANNEL",
15            SubscriptionChannel::Notifica => "NOTIFICA_CHANNEL",
16            SubscriptionChannel::BajkomatApi => "BAJKOMAT_API_CHANNEL",
17        }
18    }
19
20    pub fn from_channel(value: &str) -> Option<Self> {
21        [
22            SubscriptionChannel::Amadeus,
23            SubscriptionChannel::BajkomatApi,
24            SubscriptionChannel::Notifica,
25        ]
26        .into_iter()
27        .find(|variant| variant.get_channel() == value)
28    }
29}
30
31#[derive(Serialize, PartialEq, Debug, Deserialize)]
32pub struct ChannelMessage<T> {
33    pub channel: SubscriptionChannel,
34    pub body: Option<T>,
35}
36
37impl From<String> for SubscriptionChannel {
38    fn from(value: String) -> Self {
39        SubscriptionChannel::from_channel(&value).expect("Invalid channel string")
40    }
41}
42
43impl<T: FromRedisValue> FromRedisValue for ChannelMessage<T> {
44    fn from_redis_value(v: &Value) -> RedisResult<Self> {
45        match v {
46            Value::Array(items) => {
47                if items.len() < 2 {
48                    return Err((redis::ErrorKind::TypeError, "Not enough items").into());
49                }
50                let channel: String = redis::from_redis_value(&items[0])?;
51                let mut body: Option<T> = None;
52                for chunk in items[1..].chunks(2) {
53                    if chunk.len() == 2 {
54                        // let key: String = redis::from_redis_value(&chunk[0])?;
55                        let val  = redis::from_redis_value(&chunk[1])?;
56                        body = Some(val)
57                    }
58                }
59
60                Ok(ChannelMessage {
61                    channel: SubscriptionChannel::from(channel),
62                    body,
63                })
64            }
65            _ => Err((redis::ErrorKind::TypeError, "Unexpected Redis value").into()),
66        }
67    }
68}
69
70impl<T: Serialize> ToRedisArgs for ChannelMessage<T> {
71    fn write_redis_args<W>(&self, out: &mut W)
72    where
73        W: ?Sized + redis::RedisWrite,
74    {
75        let msg = serde_json::to_vec(&self);
76        if let Ok(message) = msg {
77            out.write_arg(&message);
78        }
79    }
80}