vapoursynth/map/
iterators.rs

1use super::*;
2
3/// An iterator over the keys of a map.
4#[derive(Debug, Clone, Copy)]
5pub struct Keys<'map, 'elem: 'map> {
6    map: &'map Map<'elem>,
7    count: usize,
8    index: usize,
9}
10
11impl<'map, 'elem> Keys<'map, 'elem> {
12    #[inline]
13    pub(crate) fn new(map: &'map Map<'elem>) -> Self {
14        Self {
15            map,
16            count: map.key_count(),
17            index: 0,
18        }
19    }
20}
21
22impl<'map, 'elem> Iterator for Keys<'map, 'elem> {
23    type Item = &'map str;
24
25    #[inline]
26    fn next(&mut self) -> Option<Self::Item> {
27        if self.index == self.count {
28            return None;
29        }
30
31        let key = self.map.key(self.index);
32        self.index += 1;
33        Some(key)
34    }
35
36    #[inline]
37    fn size_hint(&self) -> (usize, Option<usize>) {
38        let len = self.count - self.index;
39        (len, Some(len))
40    }
41}
42
43impl<'map, 'elem> ExactSizeIterator for Keys<'map, 'elem> {}
44
45/// An iterator over the values associated with a certain key of a map.
46#[derive(Debug, Clone)]
47pub struct ValueIter<'map, 'elem: 'map, T> {
48    map: &'map Map<'elem>,
49    key: CString,
50    count: i32,
51    index: i32,
52    _variance: PhantomData<fn() -> T>,
53}
54
55macro_rules! impl_value_iter {
56    ($value_type:path, $type:ty, $func:ident) => {
57        impl<'map, 'elem> $crate::map::ValueIter<'map, 'elem, $type> {
58            /// Creates a `ValueIter` from the given `map` and `key`.
59            ///
60            /// # Safety
61            /// The caller must ensure `key` is valid.
62            #[inline]
63            pub(crate) unsafe fn new(
64                map: &'map $crate::prelude::Map<'elem>,
65                key: CString,
66            ) -> $crate::map::Result<Self> {
67                // Check if the value type is correct.
68                match map.value_type_raw_unchecked(&key)? {
69                    $value_type => {}
70                    _ => return Err($crate::map::Error::WrongValueType),
71                };
72
73                let count = map.value_count_raw_unchecked(&key)? as i32;
74                Ok(Self {
75                    map,
76                    key,
77                    count,
78                    index: 0,
79                    _variance: std::marker::PhantomData,
80                })
81            }
82        }
83
84        impl<'map, 'elem> std::iter::Iterator for $crate::map::ValueIter<'map, 'elem, $type> {
85            type Item = $type;
86
87            #[inline]
88            fn next(&mut self) -> Option<Self::Item> {
89                if self.index == self.count {
90                    return None;
91                }
92
93                let value = unsafe { self.map.$func(&self.key, self.index).unwrap() };
94                self.index += 1;
95
96                Some(value)
97            }
98
99            #[inline]
100            fn size_hint(&self) -> (usize, Option<usize>) {
101                let len = (self.count - self.index) as usize;
102                (len, Some(len))
103            }
104        }
105
106        impl<'map, 'elem> std::iter::ExactSizeIterator
107            for $crate::map::ValueIter<'map, 'elem, $type>
108        {
109        }
110    };
111}
112
113impl_value_iter!(ValueType::Int, i64, get_int_raw_unchecked);
114impl_value_iter!(ValueType::Float, f64, get_float_raw_unchecked);
115impl_value_iter!(ValueType::Data, &'map [u8], get_data_raw_unchecked);
116impl_value_iter!(
117    ValueType::VideoNode,
118    Node<'elem>,
119    get_video_node_raw_unchecked
120);
121impl_value_iter!(
122    ValueType::VideoFrame,
123    FrameRef<'elem>,
124    get_video_frame_raw_unchecked
125);
126impl_value_iter!(
127    ValueType::Function,
128    Function<'elem>,
129    get_function_raw_unchecked
130);