flippico_cache/types/
provider.rs

1use 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}