use crate::consumer_contracts::types::{Consumer, ConsumerIdentifier};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use uuid::Uuid;
#[derive(Debug, Clone)]
pub struct ConsumerRegistry {
consumers: Arc<RwLock<HashMap<String, Consumer>>>,
identifier_index: Arc<RwLock<HashMap<ConsumerIdentifier, String>>>,
}
impl ConsumerRegistry {
pub fn new() -> Self {
Self {
consumers: Arc::new(RwLock::new(HashMap::new())),
identifier_index: Arc::new(RwLock::new(HashMap::new())),
}
}
pub async fn register(&self, consumer: Consumer) {
let id = consumer.id.clone();
let identifier = consumer.identifier.clone();
{
let mut consumers = self.consumers.write().await;
consumers.insert(id.clone(), consumer);
}
{
let mut index = self.identifier_index.write().await;
index.insert(identifier, id);
}
}
pub async fn get_by_id(&self, id: &str) -> Option<Consumer> {
let consumers = self.consumers.read().await;
consumers.get(id).cloned()
}
pub async fn get_by_identifier(&self, identifier: &ConsumerIdentifier) -> Option<Consumer> {
let consumer_id = {
let index = self.identifier_index.read().await;
index.get(identifier).cloned()
};
if let Some(consumer_id) = consumer_id {
self.get_by_id(&consumer_id).await
} else {
None
}
}
pub async fn list_all(&self) -> Vec<Consumer> {
let consumers = self.consumers.read().await;
consumers.values().cloned().collect()
}
pub async fn remove(&self, id: &str) -> Option<Consumer> {
let consumer = {
let mut consumers = self.consumers.write().await;
consumers.remove(id)
};
if let Some(ref consumer) = consumer {
let mut index = self.identifier_index.write().await;
index.remove(&consumer.identifier);
}
consumer
}
pub async fn get_or_create(
&self,
identifier: ConsumerIdentifier,
name: String,
workspace_id: Option<String>,
) -> Consumer {
if let Some(consumer) = self.get_by_identifier(&identifier).await {
return consumer;
}
let id = Uuid::new_v4().to_string();
let consumer = Consumer::new(id, identifier, name, workspace_id);
self.register(consumer.clone()).await;
consumer
}
}
impl Default for ConsumerRegistry {
fn default() -> Self {
Self::new()
}
}