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