1use super::*;
2use windows_core::*;
3
4struct StockMap<K, V>
5where
6 K: RuntimeType + 'static,
7 V: RuntimeType + 'static,
8 K::Default: Clone + Ord,
9 V::Default: Clone,
10{
11 map: std::sync::RwLock<std::collections::BTreeMap<K::Default, V::Default>>,
12}
13
14implement_decl! {
15 impl<K, V> StockMap as StockMap_Impl: [
16 IMap<K, V>,
17 IIterable<IKeyValuePair<K, V>>,
18 ]
19 where K: RuntimeType + 'static, V: RuntimeType + 'static, K::Default: Clone + Ord, V::Default: Clone
20}
21
22impl<K, V> IIterable_Impl<IKeyValuePair<K, V>> for StockMap_Impl<K, V>
23where
24 K: RuntimeType,
25 V: RuntimeType,
26 K::Default: Clone + Ord,
27 V::Default: Clone,
28{
29 fn First(&self) -> Result<IIterator<IKeyValuePair<K, V>>> {
30 let snapshot: Vec<(K::Default, V::Default)> = self
31 .map
32 .read()
33 .unwrap()
34 .iter()
35 .map(|(k, v)| (k.clone(), v.clone()))
36 .collect();
37 Ok(ComObject::new(StockMapIterator::<K, V> {
38 snapshot,
39 current: 0.into(),
40 })
41 .into_interface())
42 }
43}
44
45impl<K, V> IMap_Impl<K, V> for StockMap_Impl<K, V>
46where
47 K: RuntimeType,
48 V: RuntimeType,
49 K::Default: Clone + Ord,
50 V::Default: Clone,
51{
52 fn Lookup(&self, key: Ref<K>) -> Result<V> {
53 let map = self.map.read().unwrap();
54 let value = map
55 .get(ref_as_default::<K>(&key))
56 .ok_or_else(|| Error::from(E_BOUNDS))?;
57 V::from_default(value)
58 }
59
60 fn Size(&self) -> Result<u32> {
61 Ok(self.map.read().unwrap().len().try_into()?)
62 }
63
64 fn HasKey(&self, key: Ref<K>) -> Result<bool> {
65 Ok(self
66 .map
67 .read()
68 .unwrap()
69 .contains_key(ref_as_default::<K>(&key)))
70 }
71
72 fn GetView(&self) -> Result<IMapView<K, V>> {
73 let snapshot = self.map.read().unwrap().clone();
74 Ok(IMapView::<K, V>::from(snapshot))
75 }
76
77 fn Insert(&self, key: Ref<K>, value: Ref<V>) -> Result<bool> {
78 let mut map = self.map.write().unwrap();
79 let replaced = map.contains_key(ref_as_default::<K>(&key));
80 map.insert(
81 ref_as_default::<K>(&key).clone(),
82 ref_as_default::<V>(&value).clone(),
83 );
84 Ok(replaced)
85 }
86
87 fn Remove(&self, key: Ref<K>) -> Result<()> {
88 let mut map = self.map.write().unwrap();
89 if map.remove(ref_as_default::<K>(&key)).is_none() {
90 return Err(Error::from(E_BOUNDS));
91 }
92 Ok(())
93 }
94
95 fn Clear(&self) -> Result<()> {
96 self.map.write().unwrap().clear();
97 Ok(())
98 }
99}
100
101struct StockMapIterator<K, V>
102where
103 K: RuntimeType + 'static,
104 V: RuntimeType + 'static,
105 K::Default: Clone + Ord,
106 V::Default: Clone,
107{
108 snapshot: Vec<(K::Default, V::Default)>,
109 current: std::sync::atomic::AtomicUsize,
110}
111
112implement_decl! {
113 impl<K, V> StockMapIterator as StockMapIterator_Impl: [
114 IIterator<IKeyValuePair<K, V>>,
115 ]
116 where K: RuntimeType + 'static, V: RuntimeType + 'static, K::Default: Clone + Ord, V::Default: Clone
117}
118
119impl<K, V> IIterator_Impl<IKeyValuePair<K, V>> for StockMapIterator_Impl<K, V>
120where
121 K: RuntimeType,
122 V: RuntimeType,
123 K::Default: Clone + Ord,
124 V::Default: Clone,
125{
126 fn Current(&self) -> Result<IKeyValuePair<K, V>> {
127 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
128 if let Some((key, value)) = self.snapshot.get(current) {
129 Ok(ComObject::new(key_value_pair::StockKeyValuePair {
130 key: key.clone(),
131 value: value.clone(),
132 })
133 .into_interface())
134 } else {
135 Err(Error::from(E_BOUNDS))
136 }
137 }
138
139 fn HasCurrent(&self) -> Result<bool> {
140 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
141 Ok(self.snapshot.len() > current)
142 }
143
144 fn MoveNext(&self) -> Result<bool> {
145 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
146 let len = self.snapshot.len();
147 if current < len {
148 self.current
149 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
150 }
151 Ok(len > current + 1)
152 }
153
154 fn GetMany(&self, items: &mut [Option<IKeyValuePair<K, V>>]) -> Result<u32> {
155 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
156 if current >= self.snapshot.len() {
157 return Ok(0);
158 }
159
160 let actual = std::cmp::min(self.snapshot.len() - current, items.len());
161 let (items, _) = items.split_at_mut(actual);
162
163 for (item, (key, value)) in items.iter_mut().zip(self.snapshot[current..].iter()) {
164 *item = Some(
165 ComObject::new(key_value_pair::StockKeyValuePair {
166 key: key.clone(),
167 value: value.clone(),
168 })
169 .into_interface(),
170 );
171 }
172
173 self.current
174 .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
175
176 Ok(actual as u32)
177 }
178}
179
180impl<K, V> From<std::collections::BTreeMap<K::Default, V::Default>> for IMap<K, V>
181where
182 K: RuntimeType,
183 V: RuntimeType,
184 K::Default: Clone + Ord,
185 V::Default: Clone,
186{
187 fn from(map: std::collections::BTreeMap<K::Default, V::Default>) -> Self {
189 ComObject::new(StockMap {
190 map: std::sync::RwLock::new(map),
191 })
192 .into_interface()
193 }
194}