Skip to main content

alibi_core/plugin/
extensions.rs

1use std::any::{Any, TypeId};
2use std::collections::HashMap;
3use std::sync::Arc;
4
5/// Typed settings and callbacks published during plugin initialization.
6///
7/// Registration is complete before requests begin; readers share immutable
8/// values rather than interpreting configuration through JSON metadata.
9#[derive(Clone, Default)]
10pub struct ContextExtensions(HashMap<TypeId, Arc<dyn Any + Send + Sync>>);
11
12impl ContextExtensions {
13    pub fn insert<T: Any + Send + Sync>(&mut self, value: T) {
14        _ = self.0.insert(TypeId::of::<T>(), Arc::new(value));
15    }
16
17    #[must_use]
18    pub fn get<T: Any + Send + Sync>(&self) -> Option<Arc<T>> {
19        Arc::clone(self.0.get(&TypeId::of::<T>())?).downcast().ok()
20    }
21}
22
23impl ContextExtensions {
24    /// An owned copy of the registered value, or its default when absent.
25    #[must_use]
26    pub(crate) fn cloned_or_default<T: Any + Send + Sync + Clone + Default>(&self) -> T {
27        self.get::<T>()
28            .map(|value| (*value).clone())
29            .unwrap_or_default()
30    }
31}
32
33impl std::fmt::Debug for ContextExtensions {
34    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
35        f.debug_struct("ContextExtensions").finish_non_exhaustive()
36    }
37}