windows_collections/
vector_view.rs

1use super::*;
2use windows_core::*;
3
4#[implement(IVectorView<T>, IIterable<T>)]
5struct StockVectorView<T>
6where
7    T: RuntimeType + 'static,
8    T::Default: Clone + PartialEq,
9{
10    values: Vec<T::Default>,
11}
12
13impl<T> IIterable_Impl<T> for StockVectorView_Impl<T>
14where
15    T: RuntimeType,
16    T::Default: Clone + PartialEq,
17{
18    fn First(&self) -> Result<IIterator<T>> {
19        Ok(ComObject::new(StockVectorViewIterator {
20            owner: self.to_object(),
21            current: 0.into(),
22        })
23        .into_interface())
24    }
25}
26
27impl<T> IVectorView_Impl<T> for StockVectorView_Impl<T>
28where
29    T: RuntimeType,
30    T::Default: Clone + PartialEq,
31{
32    fn GetAt(&self, index: u32) -> Result<T> {
33        let item = self
34            .values
35            .get(index as usize)
36            .ok_or_else(|| Error::from(E_BOUNDS))?;
37
38        T::from_default(item)
39    }
40
41    fn Size(&self) -> Result<u32> {
42        Ok(self.values.len().try_into()?)
43    }
44
45    fn IndexOf(&self, value: Ref<T>, result: &mut u32) -> Result<bool> {
46        match self.values.iter().position(|element| element == &*value) {
47            Some(index) => {
48                *result = index as u32;
49                Ok(true)
50            }
51            None => Ok(false),
52        }
53    }
54
55    fn GetMany(&self, current: u32, values: &mut [T::Default]) -> Result<u32> {
56        let current = current as usize;
57
58        if current >= self.values.len() {
59            return Ok(0);
60        }
61
62        let actual = std::cmp::min(self.values.len() - current, values.len());
63        let (values, _) = values.split_at_mut(actual);
64        values.clone_from_slice(&self.values[current..current + actual]);
65        Ok(actual as u32)
66    }
67}
68
69#[implement(IIterator<T>)]
70struct StockVectorViewIterator<T>
71where
72    T: RuntimeType + 'static,
73    T::Default: Clone + PartialEq,
74{
75    owner: ComObject<StockVectorView<T>>,
76    current: std::sync::atomic::AtomicUsize,
77}
78
79impl<T> IIterator_Impl<T> for StockVectorViewIterator_Impl<T>
80where
81    T: RuntimeType,
82    T::Default: Clone + PartialEq,
83{
84    fn Current(&self) -> Result<T> {
85        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
86
87        if let Some(item) = self.owner.values.get(current) {
88            T::from_default(item)
89        } else {
90            Err(Error::from(E_BOUNDS))
91        }
92    }
93
94    fn HasCurrent(&self) -> Result<bool> {
95        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
96        Ok(self.owner.values.len() > current)
97    }
98
99    fn MoveNext(&self) -> Result<bool> {
100        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
101
102        if current < self.owner.values.len() {
103            self.current
104                .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
105        }
106
107        Ok(self.owner.values.len() > current + 1)
108    }
109
110    fn GetMany(&self, values: &mut [T::Default]) -> Result<u32> {
111        let current = self.current.load(std::sync::atomic::Ordering::Relaxed);
112        let actual = std::cmp::min(self.owner.values.len() - current, values.len());
113        let (values, _) = values.split_at_mut(actual);
114        values.clone_from_slice(&self.owner.values[current..current + actual]);
115
116        self.current
117            .fetch_add(actual, std::sync::atomic::Ordering::Relaxed);
118
119        Ok(actual as u32)
120    }
121}
122
123impl<T> From<Vec<T::Default>> for IVectorView<T>
124where
125    T: RuntimeType,
126    T::Default: Clone + PartialEq,
127{
128    fn from(values: Vec<T::Default>) -> Self {
129        ComObject::new(StockVectorView { values }).into_interface()
130    }
131}