ferrox_feature_flags/
lib.rs1use redis::AsyncCommands;
6use ferrox_errors::AppError;
7
8#[derive(Clone)]
9pub struct FeatureFlagsClient {
10 redis_client: redis::Client,
11}
12
13impl FeatureFlagsClient {
14 pub fn new(redis_url: &str) -> Result<Self, AppError> {
15 let redis_client = redis::Client::open(redis_url)
16 .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
17 Ok(Self { redis_client })
18 }
19
20 pub async fn is_enabled(&self, feature_name: &str) -> Result<bool, AppError> {
22 let mut con = self.redis_client.get_multiplexed_async_connection().await
23 .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
24
25 let key = format!("feature_flag:{}", feature_name);
26
27 let is_enabled: Option<bool> = con.get(&key)
28 .await
29 .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
30
31 Ok(is_enabled.unwrap_or(false))
32 }
33
34 pub async fn set_flag(&self, feature_name: &str, enabled: bool) -> Result<(), AppError> {
36 let mut con = self.redis_client.get_multiplexed_async_connection().await
37 .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
38
39 let key = format!("feature_flag:{}", feature_name);
40
41 con.set::<_, _, ()>(&key, enabled)
42 .await
43 .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
44
45 Ok(())
46 }
47}