1use core::cell::RefCell;
6
7use crate::watcher::{Context, WatcherGuard, WatcherManager};
8use alloc::{collections::btree_map::BTreeMap, rc::Rc};
9
10pub trait Dictionary {
12 type Key: 'static;
14 type Value: 'static;
16 type Guard: WatcherGuard;
18
19 fn get(&self, key: &Self::Key) -> Option<Self::Value>;
21 fn watch(
23 &self,
24 key: &Self::Key,
25 watcher: impl Fn(Context<Option<Self::Value>>) + 'static,
26 ) -> Self::Guard;
27}
28
29impl<K, V> Dictionary for BTreeMap<K, V>
30where
31 K: Ord + Clone + 'static,
32 V: Clone + 'static,
33{
34 type Key = K;
35 type Value = V;
36 type Guard = ();
37
38 fn get(&self, key: &Self::Key) -> Option<Self::Value> {
39 self.get(key).cloned()
40 }
41
42 fn watch(
43 &self,
44 _key: &Self::Key,
45 _watcher: impl Fn(Context<Option<Self::Value>>) + 'static,
46 ) -> Self::Guard {
47 }
49}
50
51#[derive(Debug)]
53pub struct Map<K, V> {
54 map: Rc<RefCell<BTreeMap<K, MapValue<V>>>>,
55}
56
57impl<K, V> Clone for Map<K, V> {
58 fn clone(&self) -> Self {
59 Self {
60 map: Rc::clone(&self.map),
61 }
62 }
63}
64
65#[derive(Debug)]
66struct MapValue<V> {
67 value: Option<V>,
68 watchers: WatcherManager<Option<V>>,
69}
70
71impl<K: Ord + Clone + 'static, V: Clone + 'static> Dictionary for Map<K, V> {
72 type Key = K;
73 type Value = V;
74 type Guard = crate::watcher::WatcherManagerGuard<Option<V>>;
75
76 fn get(&self, key: &Self::Key) -> Option<Self::Value> {
77 let map = self.map.borrow();
78 map.get(key).and_then(|mv| mv.value.clone())
79 }
80
81 fn watch(
82 &self,
83 key: &Self::Key,
84 watcher: impl Fn(Context<Option<Self::Value>>) + 'static,
85 ) -> Self::Guard {
86 let mut map = self.map.borrow_mut();
87 let mv = map.entry(key.clone()).or_insert_with(|| MapValue {
88 value: None,
89 watchers: WatcherManager::new(),
90 });
91 mv.watchers.register_as_guard(watcher)
92 }
93}
94
95#[cfg(feature = "std")]
96mod std_impls {
97 extern crate std;
98 use super::{Context, Dictionary};
99 use std::collections::HashMap;
100 use std::hash::{BuildHasher, Hash};
101
102 impl<K: Hash + Eq + Clone + 'static, V: Clone + 'static, S: BuildHasher + 'static> Dictionary
103 for HashMap<K, V, S>
104 {
105 type Key = K;
106 type Value = V;
107 type Guard = ();
108
109 fn get(&self, key: &Self::Key) -> Option<Self::Value> {
110 self.get(key).cloned()
111 }
112
113 fn watch(
114 &self,
115 _key: &Self::Key,
116 _watcher: impl Fn(Context<Option<Self::Value>>) + 'static,
117 ) -> Self::Guard {
118 }
120 }
121}