1use super::*;
2use windows_core::*;
3
4struct StockMapView<K, V>
5where
6 K: RuntimeType + 'static,
7 V: RuntimeType + 'static,
8 K::Default: Clone + Ord,
9 V::Default: Clone,
10{
11 map: std::collections::BTreeMap<K::Default, V::Default>,
12}
13
14implement_decl! {
15 impl<K, V> StockMapView as StockMapView_Impl: [
16 IMapView<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 StockMapView_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 .iter()
33 .map(|(k, v)| (k.clone(), v.clone()))
34 .collect();
35 Ok(ComObject::new(StockMapViewIterator::<K, V> {
36 snapshot,
37 current: 0.into(),
38 })
39 .into_interface())
40 }
41}
42
43impl<K, V> IMapView_Impl<K, V> for StockMapView_Impl<K, V>
44where
45 K: RuntimeType,
46 V: RuntimeType,
47 K::Default: Clone + Ord,
48 V::Default: Clone,
49{
50 fn Lookup(&self, key: Ref<K>) -> Result<V> {
51 let value = self
52 .map
53 .get(ref_as_default::<K>(&key))
54 .ok_or_else(|| Error::from(E_BOUNDS))?;
55
56 V::from_default(value)
57 }
58
59 fn Size(&self) -> Result<u32> {
60 Ok(self.map.len().try_into()?)
61 }
62
63 fn HasKey(&self, key: Ref<K>) -> Result<bool> {
64 Ok(self.map.contains_key(ref_as_default::<K>(&key)))
65 }
66
67 fn Split(&self, first: OutRef<IMapView<K, V>>, second: OutRef<IMapView<K, V>>) -> Result<()> {
68 _ = first.write(None);
69 _ = second.write(None);
70 Ok(())
71 }
72}
73
74struct StockMapViewIterator<K, V>
75where
76 K: RuntimeType + 'static,
77 V: RuntimeType + 'static,
78 K::Default: Clone + Ord,
79 V::Default: Clone,
80{
81 snapshot: Vec<(K::Default, V::Default)>,
82 current: std::sync::atomic::AtomicUsize,
83}
84
85implement_decl! {
86 impl<K, V> StockMapViewIterator as StockMapViewIterator_Impl: [
87 IIterator<IKeyValuePair<K, V>>,
88 ]
89 where K: RuntimeType + 'static, V: RuntimeType + 'static, K::Default: Clone + Ord, V::Default: Clone
90}
91
92impl<K, V> IIterator_Impl<IKeyValuePair<K, V>> for StockMapViewIterator_Impl<K, V>
93where
94 K: RuntimeType,
95 V: RuntimeType,
96 K::Default: Clone + Ord,
97 V::Default: Clone,
98{
99 fn Current(&self) -> Result<IKeyValuePair<K, V>> {
100 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
101 if let Some((key, value)) = self.snapshot.get(current) {
102 Ok(ComObject::new(key_value_pair::StockKeyValuePair {
103 key: key.clone(),
104 value: value.clone(),
105 })
106 .into_interface())
107 } else {
108 Err(Error::from(E_BOUNDS))
109 }
110 }
111
112 fn HasCurrent(&self) -> Result<bool> {
113 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
114 Ok(self.snapshot.len() > current)
115 }
116
117 fn MoveNext(&self) -> Result<bool> {
118 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
119 let len = self.snapshot.len();
120
121 if current < len {
122 self.current
123 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
124 }
125
126 Ok(len > current + 1)
127 }
128
129 fn GetMany(&self, pairs: &mut [Option<IKeyValuePair<K, V>>]) -> Result<u32> {
130 let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
131
132 if current >= self.snapshot.len() {
133 return Ok(0);
134 }
135
136 let actual = std::cmp::min(self.snapshot.len() - current, pairs.len());
137 let (pairs, _) = pairs.split_at_mut(actual);
138
139 for (pair, (key, value)) in pairs.iter_mut().zip(self.snapshot[current..].iter()) {
140 *pair = Some(
141 ComObject::new(key_value_pair::StockKeyValuePair {
142 key: key.clone(),
143 value: value.clone(),
144 })
145 .into_interface(),
146 );
147 }
148
149 self.current
150 .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
151
152 Ok(actual as u32)
153 }
154}
155
156impl<K, V> From<std::collections::BTreeMap<K::Default, V::Default>> for IMapView<K, V>
157where
158 K: RuntimeType,
159 V: RuntimeType,
160 K::Default: Clone + Ord,
161 V::Default: Clone,
162{
163 fn from(map: std::collections::BTreeMap<K::Default, V::Default>) -> Self {
165 ComObject::new(StockMapView { map }).into_interface()
166 }
167}