Skip to main content

ferrox_feature_flags/
lib.rs

1use redis::AsyncCommands;
2use ferrox_errors::AppError;
3
4#[derive(Clone)]
5pub struct FeatureFlagsClient {
6    redis_client: redis::Client,
7}
8
9impl FeatureFlagsClient {
10    pub fn new(redis_url: &str) -> Result<Self, AppError> {
11        let redis_client = redis::Client::open(redis_url)
12            .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
13        Ok(Self { redis_client })
14    }
15
16    /// Checks if a feature flag is globally enabled
17    pub async fn is_enabled(&self, feature_name: &str) -> Result<bool, AppError> {
18        let mut con = self.redis_client.get_async_connection().await
19            .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
20
21        let key = format!("feature_flag:{}", feature_name);
22        
23        let is_enabled: Option<bool> = con.get(&key)
24            .await
25            .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
26
27        Ok(is_enabled.unwrap_or(false))
28    }
29
30    /// Enables or disables a feature flag globally
31    pub async fn set_flag(&self, feature_name: &str, enabled: bool) -> Result<(), AppError> {
32        let mut con = self.redis_client.get_async_connection().await
33            .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
34
35        let key = format!("feature_flag:{}", feature_name);
36        
37        con.set(&key, enabled)
38            .await
39            .map_err(|e| AppError::InternalServerError(Box::new(e)))?;
40
41        Ok(())
42    }
43}