bloom_core/
context.rs

1use std::{
2    any::{Any, TypeId},
3    collections::HashMap,
4    sync::Arc,
5};
6
7use async_context::with_async_context;
8
9use crate::{hook::Hook, Element};
10
11pub struct Provider {
12    value: Arc<dyn Any + Send + Sync>,
13}
14
15impl Provider {
16    pub fn new<T>(value: T) -> Self
17    where
18        T: Send + Sync + 'static,
19    {
20        Self {
21            value: Arc::new(value),
22        }
23    }
24
25    pub fn children<N, E>(self, children: Vec<Element<N, E>>) -> Element<N, E>
26    where
27        N: From<String>,
28    {
29        Element::Provider(self.value, children)
30    }
31}
32
33pub(crate) type ContextMap = Arc<HashMap<TypeId, Arc<dyn Any + Send + Sync>>>;
34
35pub fn use_context<T>() -> Arc<T>
36where
37    T: Clone + Default + 'static,
38{
39    with_async_context(|hook: Option<&Hook>| {
40        if let Some(hook) = hook {
41            hook.context
42                .get(&TypeId::of::<T>())
43                .and_then(|value| value.downcast_ref::<Arc<T>>())
44                .cloned()
45                .unwrap_or(Arc::new(T::default()))
46        } else {
47            Arc::new(T::default())
48        }
49    })
50}
51
52pub fn _get_context() -> ContextMap {
53    with_async_context(|hook: Option<&Hook>| {
54        if let Some(hook) = hook {
55            hook.context.clone()
56        } else {
57            Arc::default()
58        }
59    })
60}