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    Shopify,
10}
11
12impl SubscriptionChannel {
13    pub fn get_channel(&self) -> &'static str {
14        match self {
15            SubscriptionChannel::Amadeus => "AMADEUS_CHANNEL",
16            SubscriptionChannel::Notifica => "NOTIFICA_CHANNEL",
17            SubscriptionChannel::BajkomatApi => "BAJKOMAT_API_CHANNEL",
18            SubscriptionChannel::Shopify => "SHOPIFY_CHANNEL",
19        }
20    }
21
22    pub fn from_channel(value: &str) -> Option<Self> {
23        [
24            SubscriptionChannel::Amadeus,
25            SubscriptionChannel::BajkomatApi,
26            SubscriptionChannel::Notifica,
27            SubscriptionChannel::Shopify,
28        ]
29        .into_iter()
30        .find(|variant| variant.get_channel() == value)
31    }
32}
33
34#[derive(Serialize, PartialEq, Debug, Deserialize)]
35pub enum ListChannel {
36    Amadeus,
37    Notifica,
38    BajkomatApi,
39    N8n,
40    Shopify,
41}
42
43impl ListChannel {
44    pub fn get_channel(&self) -> &'static str {
45        match self {
46            ListChannel::Amadeus => "AMADEUS_LIST",
47            ListChannel::Notifica => "NOTIFICA_LIST",
48            ListChannel::BajkomatApi => "BAJKOMAT_API_LIST",
49            ListChannel::Shopify => "SHOPIFY_LIST",
50            ListChannel::N8n => "N_8_N",
51        }
52    }
53    pub fn from_channel(value: &str) -> Option<Self> {
54        [
55            ListChannel::Amadeus,
56            ListChannel::BajkomatApi,
57            ListChannel::Notifica,
58            ListChannel::Shopify,
59            ListChannel::N8n,
60        ]
61        .into_iter()
62        .find(|variant| variant.get_channel() == value)
63    }
64}
65
66pub enum CacheSpace {
67    Amadeus,
68    Notifica,
69    BajkomatApi,
70    Shopify,
71}
72
73impl CacheSpace {
74    pub fn get_space(&self) -> &'static str {
75        match self {
76            CacheSpace::Amadeus => "AMADEUS_CACHE",
77            CacheSpace::Notifica => "NOTIFICA_CACHE",
78            CacheSpace::BajkomatApi => "BAJKOMAT_API_CACHE",
79            CacheSpace::Shopify => "SHOPIFY_CACHE",
80        }
81    }
82}
83
84#[derive(Serialize, PartialEq, Debug, Deserialize)]
85pub struct ChannelMessage {
86    pub meta: Option<MessageMeta>,
87    pub channel: SubscriptionChannel,
88    pub body: Option<serde_json::Value>,
89}
90
91#[derive(Serialize, PartialEq, Debug, Deserialize)]
92pub struct MessageMeta {
93    pub app_name: String,
94}
95
96#[derive(Serialize, PartialEq, Debug, Deserialize)]
97pub struct ListMessage {
98    pub meta: Option<MessageMeta>,
99    pub body: Option<serde_json::Value>,
100}
101
102#[derive(Serialize, PartialEq, Debug, Deserialize)]
103pub struct CacheValue<T> {
104    pub meta: Option<MessageMeta>,
105    pub value: Option<T>,
106}
107
108impl From<String> for SubscriptionChannel {
109    fn from(value: String) -> Self {
110        SubscriptionChannel::from_channel(&value).expect("Invalid channel string")
111    }
112}
113
114impl FromRedisValue for ChannelMessage {
115    fn from_redis_value(v: &Value) -> RedisResult<Self> {
116        match v {
117            Value::Array(items) => {
118                if items.len() < 2 {
119                    return Err((redis::ErrorKind::TypeError, "Not enough items").into());
120                }
121                let channel: String = redis::from_redis_value(&items[0])?;
122                let mut body: Option<String> = None;
123                for chunk in items[1..].chunks(2) {
124                    if chunk.len() == 2 {
125                        // let key: String = redis::from_redis_value(&chunk[0])?;
126                        let val = redis::from_redis_value(&chunk[1])?;
127                        body = Some(val)
128                    }
129                }
130
131                Ok(ChannelMessage {
132                    channel: SubscriptionChannel::from(channel),
133                    // TODO to check if body is Some
134                    meta: None,
135                    body: serde_json::from_str(&body.unwrap()).unwrap(),
136                })
137            }
138            _ => Err((redis::ErrorKind::TypeError, "Unexpected Redis value").into()),
139        }
140    }
141}
142
143impl ToRedisArgs for ChannelMessage {
144    fn write_redis_args<W>(&self, out: &mut W)
145    where
146        W: ?Sized + redis::RedisWrite,
147    {
148        let msg = serde_json::to_vec(&self);
149        if let Ok(message) = msg {
150            out.write_arg(&message);
151        }
152    }
153}