itunes_com/wrappers/
iter.rs

1//! Wrapper over COM iteration ability
2//!
3//! I could not manage to make the COM API `_NewEnum` work, so I'm implementing iterators myself instead
4
5use std::marker::PhantomData;
6
7use crate::wrappers::Iterable;
8use super::LONG;
9
10pub struct Iterator<'a, Obj, Item> {
11    data: &'a Obj,
12    count: LONG,
13    current: LONG,
14    items: PhantomData<Item>,
15}
16
17impl<'a, Obj, Items> Iterator<'a, Obj, Items>
18where Obj: Iterable + Iterable<Item = Items>
19{
20    pub(crate) fn new(data: &'a Obj) -> windows::core::Result<Self> {
21        let count = data.Count()?;
22
23        Ok(Self {
24            data,
25            count,
26            current: 0,
27            items: PhantomData,
28        })
29    }
30}
31
32impl<'a, Obj, Items> std::iter::Iterator for Iterator<'a, Obj, Items>
33where Obj: Iterable + Iterable<Item = Items>
34{
35    type Item = Items;
36
37    fn next(&mut self) -> Option<Self::Item> {
38        // COM iterators (or at least iTunes iterators) are 1-based.
39        // Let's increment the index _before_ we access it.
40        self.current += 1;
41        self.data.item(self.current).ok()
42    }
43}
44
45impl<'a, Obj, Items> std::iter::ExactSizeIterator for Iterator<'a, Obj, Items>
46where Obj: Iterable + Iterable<Item = Items>
47{
48    fn len(&self) -> usize {
49        self.count as usize
50    }
51}
52
53impl<'a, Obj, Items> std::iter::DoubleEndedIterator for Iterator<'a, Obj, Items>
54where Obj: Iterable + Iterable<Item = Items>
55{
56    fn next_back(&mut self) -> Option<Self::Item> {
57        self.current -= 1;
58        self.data.item(self.current).ok()
59    }
60}
61