lash_core/provider/
registry.rs1use super::support::*;
2
3pub trait ProviderFactory: Send + Sync {
4 fn kind(&self) -> &'static str;
5
6 fn deserialize(&self, config: serde_json::Value) -> Result<ProviderComponents, String>;
8}
9
10#[derive(Clone, Default)]
11pub struct ProviderRegistry {
12 factories: BTreeMap<&'static str, Arc<dyn ProviderFactory>>,
13}
14
15impl ProviderRegistry {
16 pub fn new() -> Self {
17 Self::default()
18 }
19
20 pub fn register(&mut self, factory: Arc<dyn ProviderFactory>) {
21 self.factories.insert(factory.kind(), factory);
22 }
23
24 pub fn build_from_spec(&self, spec: &ProviderSpec) -> Result<ProviderComponents, String> {
25 let factory = self.factories.get(spec.kind.as_str()).ok_or_else(|| {
26 format!(
27 "provider `{}` is not registered. Call `lash_core::register_provider_factory` at startup.",
28 spec.kind
29 )
30 })?;
31 factory.deserialize(spec.config.clone())
32 }
33
34 pub fn factory(&self, kind: &str) -> Option<&Arc<dyn ProviderFactory>> {
35 self.factories.get(kind)
36 }
37}
38
39static PROVIDER_REGISTRY: LazyLock<RwLock<ProviderRegistry>> =
40 LazyLock::new(|| RwLock::new(ProviderRegistry::new()));
41
42pub fn register_provider_factory(factory: Arc<dyn ProviderFactory>) {
46 PROVIDER_REGISTRY.write().unwrap().register(factory);
47}
48
49pub fn build_provider(spec: &ProviderSpec) -> Result<ProviderComponents, String> {
52 PROVIDER_REGISTRY.read().unwrap().build_from_spec(spec)
53}
54
55pub fn provider_factory(kind: &str) -> Option<Arc<dyn ProviderFactory>> {
58 PROVIDER_REGISTRY.read().unwrap().factory(kind).cloned()
59}