use std::collections::HashMap;
use std::sync::Arc;
use std::sync::Mutex;
use std::sync::OnceLock;
use crate::client::name_resolution::ResolverBuilder;
static GLOBAL_RESOLVER_REGISTRY: OnceLock<ResolverRegistry> = OnceLock::new();
#[derive(Default)]
pub(crate) struct ResolverRegistry {
inner: Arc<Mutex<HashMap<String, Arc<dyn ResolverBuilder>>>>,
}
impl ResolverRegistry {
fn new() -> Self {
Self {
inner: Arc::default(),
}
}
pub fn add_builder(&self, builder: Box<dyn ResolverBuilder>) {
self.try_add_builder(builder).unwrap();
}
pub fn try_add_builder(&self, builder: Box<dyn ResolverBuilder>) -> Result<(), String> {
let scheme = builder.scheme();
if scheme.chars().any(|c| c.is_ascii_uppercase()) {
return Err(format!(
"Scheme must not contain uppercase characters: {scheme}"
));
}
self.inner
.lock()
.unwrap()
.insert(scheme.to_string(), Arc::from(builder));
Ok(())
}
pub fn get(&self, scheme: &str) -> Option<Arc<dyn ResolverBuilder>> {
self.inner
.lock()
.unwrap()
.get(&scheme.to_lowercase())
.cloned()
}
}
pub(crate) fn global_registry() -> &'static ResolverRegistry {
GLOBAL_RESOLVER_REGISTRY.get_or_init(ResolverRegistry::new)
}