gix_index/extension/
iter.rs

1use crate::{extension, extension::Iter, util::from_be_u32};
2
3impl<'a> Iter<'a> {
4    /// Create a new extension iterator at the entrypoint for extensions until the end of the extensions.
5    pub fn new(data_at_beginning_of_extensions_and_truncated: &'a [u8]) -> Self {
6        Iter {
7            data: data_at_beginning_of_extensions_and_truncated,
8            consumed: 0,
9        }
10    }
11
12    /// Create a new iterator at with a data block to the end of the file, and we automatically remove the trailing
13    /// hash of type `object_hash`.
14    pub fn new_without_checksum(
15        data_at_beginning_of_extensions: &'a [u8],
16        object_hash: gix_hash::Kind,
17    ) -> Option<Self> {
18        let end = data_at_beginning_of_extensions
19            .len()
20            .checked_sub(object_hash.len_in_bytes())?;
21        Iter {
22            data: &data_at_beginning_of_extensions[..end],
23            consumed: 0,
24        }
25        .into()
26    }
27}
28
29impl<'a> Iterator for Iter<'a> {
30    type Item = (extension::Signature, &'a [u8]);
31
32    fn next(&mut self) -> Option<Self::Item> {
33        if self.data.len() < 4 + 4 {
34            return None;
35        }
36
37        let (signature, data) = self.data.split_at(4);
38        let (size, data) = data.split_at(4);
39        self.data = data;
40        self.consumed += 4 + 4;
41
42        let size = from_be_u32(size) as usize;
43
44        match data.get(..size) {
45            Some(ext_data) => {
46                self.data = &data[size..];
47                self.consumed += size;
48                Some((signature.try_into().unwrap(), ext_data))
49            }
50            None => {
51                self.data = &[];
52                None
53            }
54        }
55    }
56}