Skip to main content

windows_collections/
vector_view.rs

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