1use crate::error::Error;
2use crate::traits::{VarInt, VarIntOps};
3use crate::encoding::decode;
4use core::marker::PhantomData;
5
6pub 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 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 pub fn index(&self) -> usize {
34 self.index
35 }
36
37 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
75pub 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 pub fn new(buf: &'a [u8]) -> Self {
86 VarIntValuesIter {
87 buf,
88 pos: 0,
89 finished: false,
90 _marker: PhantomData,
91 }
92 }
93
94 pub fn position(&self) -> usize {
96 self.pos
97 }
98
99 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
126pub fn bytes_of<T: VarInt>(value: T) -> VarIntBytesIter<T> {
128 VarIntBytesIter::new(value)
129}
130
131pub fn values_from<'a, T: VarInt>(buf: &'a [u8]) -> VarIntValuesIter<'a, T> {
133 VarIntValuesIter::new(buf)
134}