bitcoin_consensus_encoding/encode/
iter.rs1use core::fmt;
4
5use super::{Encode, Encoder, EncoderStatus};
6
7pub(super) struct Encoders<'e, T: Encode> {
15 iter: core::slice::Iter<'e, T>,
16}
17
18impl<'e, T: Encode> Encoders<'e, T> {
19 pub(super) fn new(sl: &'e [T]) -> Self { Self { iter: sl.iter() } }
20}
21
22impl<'e, T: Encode> Iterator for Encoders<'e, T> {
23 type Item = T::Encoder<'e>;
24 fn next(&mut self) -> Option<T::Encoder<'e>> {
25 #[allow(clippy::redundant_closure_for_method_calls)]
28 self.iter.next().map(|item| item.encoder())
29 }
30}
31
32impl<'e, T: Encode> fmt::Debug for Encoders<'e, T> {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 f.debug_struct("Encoders").field("remaining", &self.iter.as_slice().len()).finish()
35 }
36}
37
38impl<'e, T: Encode> Clone for Encoders<'e, T> {
39 fn clone(&self) -> Self { Self { iter: self.iter.clone() } }
40}
41
42enum EncoderState<I: Iterator>
43where
44 I::Item: Encoder,
45{
46 Encoding { current: I::Item, remaining: core::iter::Fuse<I> },
47 Done,
48}
49
50pub struct IterEncoder<I: Iterator>
54where
55 I::Item: Encoder,
56{
57 state: EncoderState<I>,
58}
59
60impl<I: Iterator> IterEncoder<I>
61where
62 I::Item: Encoder,
63{
64 pub fn new(iter: impl IntoIterator<IntoIter = I>) -> Self {
66 let mut iter = iter.into_iter().fuse();
68 let state = loop {
72 match iter.next() {
73 Some(enc) if !enc.current_chunk().is_empty() =>
74 break EncoderState::Encoding { current: enc, remaining: iter },
75 Some(_) => {}
76 None => break EncoderState::Done,
77 }
78 };
79 Self { state }
80 }
81}
82
83impl<I: Iterator> fmt::Debug for IterEncoder<I>
84where
85 I::Item: Encoder + fmt::Debug,
86{
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match &self.state {
89 EncoderState::Encoding { current, .. } =>
90 f.debug_struct("IterEncoder").field("current", current).finish(),
91 EncoderState::Done => f.debug_struct("IterEncoder").finish(),
92 }
93 }
94}
95
96impl<I: Iterator> Clone for IterEncoder<I>
97where
98 I: Clone,
99 I::Item: Encoder + Clone,
100{
101 fn clone(&self) -> Self {
102 let state = match &self.state {
103 EncoderState::Encoding { current, remaining } =>
104 EncoderState::Encoding { current: current.clone(), remaining: remaining.clone() },
105 EncoderState::Done => EncoderState::Done,
106 };
107 Self { state }
108 }
109}
110
111impl<I: Iterator> Encoder for IterEncoder<I>
112where
113 I::Item: Encoder,
114{
115 fn current_chunk(&self) -> &[u8] {
116 match &self.state {
117 EncoderState::Encoding { current, .. } => current.current_chunk(),
118 EncoderState::Done => &[],
119 }
120 }
121
122 fn advance(&mut self) -> EncoderStatus {
123 let EncoderState::Encoding { current, remaining } = &mut self.state else {
124 return EncoderStatus::Finished;
125 };
126
127 loop {
128 if current.advance().has_more() {
129 return EncoderStatus::HasMore;
130 }
131
132 if let Some(next) = remaining.next() {
133 *current = next;
134 if !current.current_chunk().is_empty() {
137 return EncoderStatus::HasMore;
138 }
139 } else {
140 self.state = EncoderState::Done;
141 return EncoderStatus::Finished;
142 }
143 }
144 }
145}