use std::{
collections::{HashMap, HashSet},
sync::{Arc, LazyLock, RwLock},
};
use super::{sink, source, transform, Component};
use crate::config::{ComponentKey, OutputId};
pub const INVARIANT: &str = "Couldn't acquire lock on Vector components. Please report this.";
pub static COMPONENTS: LazyLock<Arc<RwLock<HashMap<ComponentKey, Component>>>> =
LazyLock::new(|| Arc::new(RwLock::new(HashMap::new())));
pub fn filter_components<T>(map_func: impl Fn((&ComponentKey, &Component)) -> Option<T>) -> Vec<T> {
COMPONENTS
.read()
.expect(INVARIANT)
.iter()
.filter_map(map_func)
.collect()
}
pub fn get_components() -> Vec<Component> {
filter_components(|(_component_key, components)| Some(components.clone()))
}
pub fn get_sources() -> Vec<source::Source> {
filter_components(|(_, components)| match components {
Component::Source(s) => Some(s.clone()),
_ => None,
})
}
pub fn get_transforms() -> Vec<transform::Transform> {
filter_components(|(_, components)| match components {
Component::Transform(t) => Some(t.clone()),
_ => None,
})
}
pub fn get_sinks() -> Vec<sink::Sink> {
filter_components(|(_, components)| match components {
Component::Sink(s) => Some(s.clone()),
_ => None,
})
}
pub fn get_component_keys() -> HashSet<ComponentKey> {
COMPONENTS
.read()
.expect(INVARIANT)
.keys()
.cloned()
.collect::<HashSet<ComponentKey>>()
}
pub fn component_by_component_key(component_key: &ComponentKey) -> Option<Component> {
Some(
COMPONENTS
.read()
.expect(INVARIANT)
.get(component_key)?
.clone(),
)
}
pub fn component_by_output_id(output_id: &OutputId) -> Option<Component> {
filter_components(|(key, component)| {
if key == &output_id.component {
Some(component.clone())
} else {
None
}
})
.pop()
}
pub fn update(new_components: HashMap<ComponentKey, Component>) {
*COMPONENTS.write().expect(INVARIANT) = new_components
}