windows_collections/
iterable.rs

1use super::*;
2use windows_core::*;
3
4#[implement(IIterable<T>)]
5struct StockIterable<T>
6where
7    T: RuntimeType + 'static,
8    T::Default: Clone,
9{
10    values: Vec<T::Default>,
11}
12
13impl<T> IIterable_Impl<T> for StockIterable_Impl<T>
14where
15    T: RuntimeType,
16    T::Default: Clone,
17{
18    fn First(&self) -> Result<IIterator<T>> {
19        Ok(ComObject::new(StockIterator {
20            owner: self.to_object(),
21            current: 0.into(),
22        })
23        .into_interface())
24    }
25}
26
27#[implement(IIterator<T>)]
28struct StockIterator<T>
29where
30    T: RuntimeType + 'static,
31    T::Default: Clone,
32{
33    owner: ComObject<StockIterable<T>>,
34    current: std::sync::atomic::AtomicUsize,
35}
36
37impl<T> IIterator_Impl<T> for StockIterator_Impl<T>
38where
39    T: RuntimeType,
40    T::Default: Clone,
41{
42    fn Current(&self) -> Result<T> {
43        let owner: &StockIterable<T> = &self.owner;
44        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
45
46        if self.owner.values.len() > current {
47            T::from_default(&owner.values[current])
48        } else {
49            Err(Error::from(E_BOUNDS))
50        }
51    }
52
53    fn HasCurrent(&self) -> Result<bool> {
54        let owner: &StockIterable<T> = &self.owner;
55        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
56
57        Ok(owner.values.len() > current)
58    }
59
60    fn MoveNext(&self) -> Result<bool> {
61        let owner: &StockIterable<T> = &self.owner;
62        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
63
64        if current < owner.values.len() {
65            self.current
66                .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
67        }
68
69        Ok(owner.values.len() > current + 1)
70    }
71
72    fn GetMany(&self, values: &mut [T::Default]) -> Result<u32> {
73        let owner: &StockIterable<T> = &self.owner;
74        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
75        let actual = std::cmp::min(owner.values.len() - current, values.len());
76        let (values, _) = values.split_at_mut(actual);
77        values.clone_from_slice(&owner.values[current..current + actual]);
78
79        self.current
80            .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
81
82        Ok(actual as u32)
83    }
84}
85
86impl<T> From<Vec<T::Default>> for IIterable<T>
87where
88    T: RuntimeType,
89    T::Default: Clone,
90{
91    fn from(values: Vec<T::Default>) -> Self {
92        ComObject::new(StockIterable { values }).into_interface()
93    }
94}