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