use heromodels::models::Event as CalendarEvent; use lazy_static::lazy_static; use redis::{Client, Commands, Connection, RedisError}; use std::sync::{Arc, Mutex}; // Create a lazy static Redis client that can be used throughout the application lazy_static! { static ref REDIS_CLIENT: Arc>> = Arc::new(Mutex::new(None)); } /// Initialize the Redis client pub fn init_redis_client(redis_url: &str) -> Result<(), RedisError> { let client = redis::Client::open(redis_url)?; // Test the connection let _: Connection = client.get_connection()?; // Store the client in the lazy static let mut client_guard = REDIS_CLIENT.lock().unwrap(); *client_guard = Some(client); Ok(()) } /// Get a Redis connection pub fn get_connection() -> Result { let client_guard = REDIS_CLIENT.lock().unwrap(); if let Some(client) = &*client_guard { client.get_connection() } else { Err(RedisError::from(std::io::Error::new( std::io::ErrorKind::NotConnected, "Redis client not initialized", ))) } } /// Redis service for calendar events pub struct RedisCalendarService; impl RedisCalendarService { /// Key prefix for calendar events const EVENT_KEY_PREFIX: &'static str = "calendar:event:"; /// Key for the set of all event IDs const ALL_EVENTS_KEY: &'static str = "calendar:all_events"; /// Save a calendar event to Redis pub fn save_event(event: &CalendarEvent) -> Result<(), RedisError> { let mut conn = get_connection()?; // Convert the event to JSON let json = event.to_json().map_err(|e| { RedisError::from(std::io::Error::new( std::io::ErrorKind::InvalidData, format!("Failed to serialize event: {}", e), )) })?; // Save the event let event_key = format!("{}{}", Self::EVENT_KEY_PREFIX, event.base_data.id); let _: () = conn.set(event_key, json)?; // Add the event ID to the set of all events let _: () = conn.sadd(Self::ALL_EVENTS_KEY, &event.base_data.id)?; Ok(()) } /// Get a calendar event from Redis by ID pub fn get_event(id: &str) -> Result, RedisError> { let mut conn = get_connection()?; // Get the event JSON let event_key = format!("{}{}", Self::EVENT_KEY_PREFIX, id); let json: Option = conn.get(event_key)?; // Parse the JSON if let Some(json) = json { let event = CalendarEvent::from_json(&json).map_err(|e| { RedisError::from(std::io::Error::new( std::io::ErrorKind::InvalidData, format!("Failed to deserialize event: {}", e), )) })?; Ok(Some(event)) } else { Ok(None) } } /// Delete a calendar event from Redis pub fn delete_event(id: &str) -> Result { let mut conn = get_connection()?; // Delete the event let event_key = format!("{}{}", Self::EVENT_KEY_PREFIX, id); let deleted: i32 = conn.del(event_key)?; // Remove the event ID from the set of all events let _: () = conn.srem(Self::ALL_EVENTS_KEY, id)?; Ok(deleted > 0) } /// Get all calendar events from Redis pub fn get_all_events() -> Result, RedisError> { let mut conn = get_connection()?; // Get all event IDs let event_ids: Vec = conn.smembers(Self::ALL_EVENTS_KEY)?; // Get all events let mut events = Vec::new(); for id in event_ids { if let Some(event) = Self::get_event(&id)? { events.push(event); } } Ok(events) } /// Get events for a specific date range pub fn get_events_in_range( start: chrono::DateTime, end: chrono::DateTime, ) -> Result, RedisError> { let all_events = Self::get_all_events()?; // Filter events that fall within the date range let filtered_events = all_events .into_iter() .filter(|event| event.start_time <= end && event.end_time >= start) .collect(); Ok(filtered_events) } }