tiny_varint/
iter.rs

1use crate::error::Error;
2use crate::traits::{VarInt, VarIntOps};
3use crate::encoding::decode;
4use core::marker::PhantomData;
5
6/// Iterator representing varint encoded bytes
7pub struct VarIntBytesIter<T: VarInt = u64> 
8where T::Unsigned: VarIntOps {
9    value: T::Unsigned,  
10    index: usize,
11    size: usize,
12    finished: bool,
13    _marker: PhantomData<T>,
14}
15
16impl<T: VarInt> VarIntBytesIter<T> 
17where T::Unsigned: VarIntOps {
18    /// Creates a new varint bytes iterator
19    pub fn new(value: T) -> Self {
20        let unsigned = value.to_unsigned();
21        let size = value.varint_size();
22        
23        VarIntBytesIter {
24            value: unsigned,
25            index: 0,
26            size,
27            finished: false,
28            _marker: PhantomData,
29        }
30    }
31    
32    /// Gets the current index
33    pub fn index(&self) -> usize {
34        self.index
35    }
36    
37    /// Gets the size of the encoded value without iterating
38    pub fn size(&self) -> usize {
39        self.size
40    }
41}
42
43impl<T: VarInt> Iterator for VarIntBytesIter<T> 
44where T::Unsigned: VarIntOps {
45    type Item = u8;
46    
47    fn next(&mut self) -> Option<Self::Item> {
48        if self.finished {
49            return None;
50        }
51        
52        let byte = if self.value.needs_another_byte() {
53            self.value.get_byte_with_continuation()
54        } else {
55            self.finished = true;
56            self.value.get_final_byte()
57        };
58        
59        self.value = self.value.shift_right_7();
60        self.index += 1;
61        
62        Some(byte)
63    }
64    
65    fn size_hint(&self) -> (usize, Option<usize>) {
66        if self.finished {
67            (0, Some(0))
68        } else {
69            let remaining = self.size.saturating_sub(self.index);
70            (remaining.min(1), Some(remaining))
71        }
72    }
73}
74
75/// Iterator for decoding varint values from a byte buffer
76pub struct VarIntValuesIter<'a, T: VarInt = u64> {
77    buf: &'a [u8],
78    pos: usize,
79    finished: bool,
80    _marker: PhantomData<T>,
81}
82
83impl<'a, T: VarInt> VarIntValuesIter<'a, T> {
84    /// Creates a new varint decoder iterator
85    pub fn new(buf: &'a [u8]) -> Self {
86        VarIntValuesIter {
87            buf,
88            pos: 0,
89            finished: false,
90            _marker: PhantomData,
91        }
92    }
93    
94    /// Gets the current position
95    pub fn position(&self) -> usize {
96        self.pos
97    }
98    
99    /// Gets the remaining buffer
100    pub fn remaining(&self) -> &'a [u8] {
101        &self.buf[self.pos..]
102    }
103}
104
105impl<'a, T: VarInt> Iterator for VarIntValuesIter<'a, T> {
106    type Item = Result<T, Error>;
107    
108    fn next(&mut self) -> Option<Self::Item> {
109        if self.finished || self.pos >= self.buf.len() {
110            return None;
111        }
112        
113        match decode::<T>(&self.buf[self.pos..]) {
114            Ok((value, bytes_read)) => {
115                self.pos += bytes_read;
116                Some(Ok(value))
117            }
118            Err(e) => {
119                self.finished = true;
120                Some(Err(e))
121            }
122        }
123    }
124}
125
126/// Helper function to create a bytes encoder for a value
127pub fn bytes_of<T: VarInt>(value: T) -> VarIntBytesIter<T> {
128    VarIntBytesIter::new(value)
129}
130
131/// Helper function to create a values decoder from a buffer
132pub fn values_from<'a, T: VarInt>(buf: &'a [u8]) -> VarIntValuesIter<'a, T> {
133    VarIntValuesIter::new(buf)
134}