flippico_cache/types/
provider.rs1use redis::Client;
2use serde_json;
3
4use crate::{
5 providers::redis::Redis,
6 types::channels::{ChannelMessage, SubscriptionChannel},
7};
8use dotenv::dotenv;
9use std::env;
10use std::future::Future;
11use std::pin::Pin;
12
13pub trait ProviderTrait {
14 fn new(url: String) -> Self
15 where
16 Self: Sized;
17}
18
19pub trait Connectable {
20 fn set_client(&mut self);
21 fn get_connection(&self) -> &Client;
22 fn get_mut_connection(&mut self) -> &mut Client;
23}
24
25pub type PubSubProviderError = &'static str;
26
27pub trait PubSubProvider {
28 type Channels;
29 fn subscribe(
30 &self,
31 callback: Box<dyn Fn(ChannelMessage<serde_json::Value>) + Send + Sync>,
32 channel: Self::Channels,
33 ) -> Pin<Box<dyn Future<Output = Result<(), &'static str>> + Send + '_>>;
34 fn publish(&mut self, channel: Self::Channels, message: ChannelMessage<serde_json::Value>);
35}
36
37pub trait ConnectableProvider: ProviderTrait + Connectable {}
38impl<T> ConnectableProvider for T where T: ProviderTrait + Connectable {}
39
40pub trait ConnectablePubSubProvider: ConnectableProvider + PubSubProvider {}
41impl<T> ConnectablePubSubProvider for T where T: ConnectableProvider + PubSubProvider {}
42
43pub enum Provider {
44 Redis,
45}
46
47pub enum ProviderEither {
48 Left(Box<dyn ConnectablePubSubProvider<Channels = SubscriptionChannel> + Send + Sync>),
49 Right(Box<dyn ConnectableProvider + Send + Sync>),
50}
51
52impl ProviderEither {
53 pub fn pub_sub(
54 self,
55 ) -> Result<
56 Box<dyn ConnectablePubSubProvider<Channels = SubscriptionChannel> + Send + Sync>,
57 &'static str,
58 > {
59 match self {
60 ProviderEither::Left(provider) => Ok(provider),
61 ProviderEither::Right(_) => Err("Wrong provider"),
62 }
63 }
64
65 pub fn connectable(self) -> Result<Box<dyn ConnectableProvider + Send + Sync>, &'static str> {
66 match self {
67 ProviderEither::Right(provider) => Ok(provider),
68 ProviderEither::Left(_) => Err("Wrong provider"),
69 }
70 }
71}
72
73impl Provider {
74 pub(crate) fn create_provider(&self) -> ProviderEither {
75 match self {
76 Provider::Redis => {
77 dotenv().ok();
78 let url = env::var("FLIPPICO_CACHE_REDIS_URL");
79 if let Ok(url) = url {
80 let mut provider = Redis::new(url);
81 provider.set_client();
82 ProviderEither::Left(Box::new(provider))
83 } else {
84 log::error!("FLIPPICO_CACHE_REDIS_URL is not set");
85 panic!("FLIPPICO_CACHE_REDIS_URL is not set");
86 }
87 }
88 }
89 }
90}