use redis::{FromRedisValue, RedisResult, ToRedisArgs, Value};
use serde::{Deserialize, Serialize};
#[derive(Serialize, PartialEq, Debug, Deserialize)]
pub enum SubscriptionChannel {
Amadeus,
Notifica,
BajkomatApi,
Shopify,
}
impl SubscriptionChannel {
pub fn get_channel(&self) -> &'static str {
match self {
SubscriptionChannel::Amadeus => "AMADEUS_CHANNEL",
SubscriptionChannel::Notifica => "NOTIFICA_CHANNEL",
SubscriptionChannel::BajkomatApi => "BAJKOMAT_API_CHANNEL",
SubscriptionChannel::Shopify => "SHOPIFY_CHANNEL",
}
}
pub fn from_channel(value: &str) -> Option<Self> {
[
SubscriptionChannel::Amadeus,
SubscriptionChannel::BajkomatApi,
SubscriptionChannel::Notifica,
SubscriptionChannel::Shopify,
]
.into_iter()
.find(|variant| variant.get_channel() == value)
}
}
#[derive(Serialize, PartialEq, Debug, Deserialize)]
pub enum ListChannel {
Amadeus,
Notifica,
BajkomatApi,
KsefGpt,
N8n,
Shopify,
}
impl ListChannel {
pub fn get_channel(&self) -> &'static str {
match self {
ListChannel::Amadeus => "AMADEUS_LIST",
ListChannel::Notifica => "NOTIFICA_LIST",
ListChannel::BajkomatApi => "BAJKOMAT_API_LIST",
ListChannel::KsefGpt => "KSEF_GPT_LISt",
ListChannel::Shopify => "SHOPIFY_LIST",
ListChannel::N8n => "N_8_N",
}
}
pub fn from_channel(value: &str) -> Option<Self> {
[
ListChannel::Amadeus,
ListChannel::BajkomatApi,
ListChannel::KsefGpt,
ListChannel::Notifica,
ListChannel::Shopify,
ListChannel::N8n,
]
.into_iter()
.find(|variant| variant.get_channel() == value)
}
}
pub enum CacheSpace {
Amadeus,
Notifica,
BajkomatApi,
Shopify,
KsefGpt,
}
impl CacheSpace {
pub fn get_space(&self) -> &'static str {
match self {
CacheSpace::Amadeus => "AMADEUS_CACHE",
CacheSpace::Notifica => "NOTIFICA_CACHE",
CacheSpace::BajkomatApi => "BAJKOMAT_API_CACHE",
CacheSpace::Shopify => "SHOPIFY_CACHE",
CacheSpace::KsefGpt => "KSEFGPT_CACHE",
}
}
}
#[derive(Serialize, PartialEq, Debug, Deserialize)]
pub struct ChannelMessage {
pub meta: Option<MessageMeta>,
pub channel: SubscriptionChannel,
pub body: Option<serde_json::Value>,
}
#[derive(Serialize, PartialEq, Debug, Deserialize)]
pub struct MessageMeta {
pub app_name: String,
}
#[derive(Serialize, PartialEq, Debug, Deserialize)]
pub struct ListMessage {
pub meta: Option<MessageMeta>,
pub body: Option<serde_json::Value>,
}
#[derive(Serialize, PartialEq, Debug, Deserialize)]
pub struct CacheValue<T> {
pub meta: Option<MessageMeta>,
pub value: Option<T>,
}
impl From<String> for SubscriptionChannel {
fn from(value: String) -> Self {
SubscriptionChannel::from_channel(&value).expect("Invalid channel string")
}
}
impl FromRedisValue for ChannelMessage {
fn from_redis_value(v: &Value) -> RedisResult<Self> {
match v {
Value::Array(items) => {
if items.len() < 2 {
return Err((redis::ErrorKind::TypeError, "Not enough items").into());
}
let channel: String = redis::from_redis_value(&items[0])?;
let mut body: Option<String> = None;
for chunk in items[1..].chunks(2) {
if chunk.len() == 2 {
let val = redis::from_redis_value(&chunk[1])?;
body = Some(val)
}
}
Ok(ChannelMessage {
channel: SubscriptionChannel::from(channel),
meta: None,
body: serde_json::from_str(&body.unwrap()).unwrap(),
})
}
_ => Err((redis::ErrorKind::TypeError, "Unexpected Redis value").into()),
}
}
}
impl ToRedisArgs for ChannelMessage {
fn write_redis_args<W>(&self, out: &mut W)
where
W: ?Sized + redis::RedisWrite,
{
let msg = serde_json::to_vec(&self);
if let Ok(message) = msg {
out.write_arg(&message);
}
}
}