use std::collections::HashMap;
use std::sync::Arc;
use crate::error::Error;
use crate::topic::PipelineTopicBinding;
use otel_arrow_dfe_config::TopicName;
use parking_lot::RwLock;
pub struct TopicSet<T: Send + Sync + 'static> {
inner: Arc<TopicSetInner<T>>,
}
impl<T: Send + Sync + 'static> Clone for TopicSet<T> {
fn clone(&self) -> Self {
Self {
inner: Arc::clone(&self.inner),
}
}
}
struct TopicSetInner<T: Send + Sync + 'static> {
name: Arc<str>,
topics: RwLock<HashMap<TopicName, PipelineTopicBinding<T>>>,
}
impl<T: Send + Sync + 'static> TopicSet<T> {
pub fn new(name: impl Into<Arc<str>>) -> Self {
Self {
inner: Arc::new(TopicSetInner {
name: name.into(),
topics: RwLock::new(HashMap::new()),
}),
}
}
#[must_use]
pub fn name(&self) -> &str {
&self.inner.name
}
pub fn insert(
&self,
local_name: impl Into<TopicName>,
binding: impl Into<PipelineTopicBinding<T>>,
) -> Option<PipelineTopicBinding<T>> {
let mut topics = self.inner.topics.write();
topics.insert(local_name.into(), binding.into())
}
#[must_use]
pub fn remove(&self, local_name: impl AsRef<str>) -> Option<PipelineTopicBinding<T>> {
let local_name = local_name.as_ref();
let mut topics = self.inner.topics.write();
topics.remove(local_name)
}
#[must_use]
pub fn get(&self, local_name: impl AsRef<str>) -> Option<PipelineTopicBinding<T>> {
let local_name = local_name.as_ref();
let topics = self.inner.topics.read();
topics.get(local_name).cloned()
}
pub fn get_required(
&self,
local_name: impl AsRef<str>,
) -> Result<PipelineTopicBinding<T>, Error> {
let local_name = local_name.as_ref();
self.get(local_name).ok_or_else(|| Error::UnknownTopic {
topic: local_name.to_owned(),
})
}
#[must_use]
pub fn contains(&self, local_name: impl AsRef<str>) -> bool {
let local_name = local_name.as_ref();
let topics = self.inner.topics.read();
topics.contains_key(local_name)
}
#[must_use]
pub fn topic_names(&self) -> Vec<TopicName> {
let topics = self.inner.topics.read();
topics.keys().cloned().collect()
}
#[must_use]
pub fn len(&self) -> usize {
let topics = self.inner.topics.read();
topics.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
let topics = self.inner.topics.read();
topics.is_empty()
}
}