tidecoin_consensus_encoding/encode/
encoders.rs1use core::fmt;
14
15use super::{Encodable, Encoder, ExactSizeEncoder};
16
17#[derive(Debug, Clone)]
19pub struct BytesEncoder<'sl> {
20 sl: Option<&'sl [u8]>,
21}
22
23impl<'sl> BytesEncoder<'sl> {
24 pub const fn without_length_prefix(sl: &'sl [u8]) -> Self {
26 Self { sl: Some(sl) }
27 }
28}
29
30impl Encoder for BytesEncoder<'_> {
31 fn current_chunk(&self) -> &[u8] {
32 self.sl.unwrap_or_default()
33 }
34
35 fn advance(&mut self) -> bool {
36 self.sl = None;
37 false
38 }
39}
40
41impl<'sl> ExactSizeEncoder for BytesEncoder<'sl> {
42 #[inline]
43 fn len(&self) -> usize {
44 self.sl.map_or(0, <[u8]>::len)
45 }
46}
47
48#[derive(Debug, Clone)]
50pub struct ArrayEncoder<const N: usize> {
51 arr: Option<[u8; N]>,
52}
53
54impl<const N: usize> ArrayEncoder<N> {
55 pub const fn without_length_prefix(arr: [u8; N]) -> Self {
57 Self { arr: Some(arr) }
58 }
59}
60
61impl<const N: usize> Encoder for ArrayEncoder<N> {
62 #[inline]
63 fn current_chunk(&self) -> &[u8] {
64 self.arr.as_ref().map(|x| &x[..]).unwrap_or_default()
65 }
66
67 #[inline]
68 fn advance(&mut self) -> bool {
69 self.arr = None;
70 false
71 }
72}
73
74impl<const N: usize> ExactSizeEncoder for ArrayEncoder<N> {
75 #[inline]
76 fn len(&self) -> usize {
77 self.arr.map_or(0, |a| a.len())
78 }
79}
80
81#[derive(Debug, Clone)]
86pub struct ArrayRefEncoder<'e, const N: usize> {
87 arr: Option<&'e [u8; N]>,
88}
89
90impl<'e, const N: usize> ArrayRefEncoder<'e, N> {
91 pub const fn without_length_prefix(arr: &'e [u8; N]) -> Self {
93 Self { arr: Some(arr) }
94 }
95}
96
97impl<const N: usize> Encoder for ArrayRefEncoder<'_, N> {
98 #[inline]
99 fn current_chunk(&self) -> &[u8] {
100 self.arr.map(|x| &x[..]).unwrap_or_default()
101 }
102
103 #[inline]
104 fn advance(&mut self) -> bool {
105 self.arr = None;
106 false
107 }
108}
109
110impl<const N: usize> ExactSizeEncoder for ArrayRefEncoder<'_, N> {
111 #[inline]
112 fn len(&self) -> usize {
113 self.arr.map_or(0, |a| a.len())
114 }
115}
116
117pub struct SliceEncoder<'e, T: Encodable> {
119 sl: &'e [T],
121 cur_enc: Option<T::Encoder<'e>>,
123}
124
125impl<'e, T: Encodable> SliceEncoder<'e, T> {
126 pub fn without_length_prefix(sl: &'e [T]) -> Self {
132 Self { sl, cur_enc: sl.first().map(|x| T::encoder(x)) }
136 }
137}
138
139impl<'e, T: Encodable> fmt::Debug for SliceEncoder<'e, T>
140where
141 T::Encoder<'e>: fmt::Debug,
142{
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 f.debug_struct("SliceEncoder")
145 .field("sl", &self.sl.len())
146 .field("cur_enc", &self.cur_enc)
147 .finish()
148 }
149}
150
151impl<'e, T: Encodable> Clone for SliceEncoder<'e, T>
154where
155 T::Encoder<'e>: Clone,
156{
157 fn clone(&self) -> Self {
158 Self { sl: self.sl, cur_enc: self.cur_enc.clone() }
159 }
160}
161
162impl<T: Encodable> Encoder for SliceEncoder<'_, T> {
163 fn current_chunk(&self) -> &[u8] {
164 self.cur_enc.as_ref().map(T::Encoder::current_chunk).unwrap_or_default()
166 }
167
168 fn advance(&mut self) -> bool {
169 let Some(cur) = self.cur_enc.as_mut() else {
170 return false;
171 };
172
173 loop {
174 if cur.advance() {
177 return true;
178 }
179 self.sl = &self.sl[1..];
181
182 if let Some(x) = self.sl.first() {
184 *cur = x.encoder();
185 if !cur.current_chunk().is_empty() {
186 return true;
187 }
188 } else {
189 self.cur_enc = None; return false;
191 }
192 }
193 }
194}
195
196impl<'e, T> ExactSizeEncoder for SliceEncoder<'e, T>
197where
198 T: Encodable + 'e,
199 T::Encoder<'e>: ExactSizeEncoder,
200{
201 fn len(&self) -> usize {
202 let Some(cur_enc) = self.cur_enc.as_ref() else {
203 return 0;
204 };
205
206 let rest = self.sl.get(1..).unwrap_or_default().iter().map(|item| item.encoder().len());
207 cur_enc.len() + rest.sum::<usize>()
208 }
209}
210
211macro_rules! define_encoder_n {
213 (
214 $(#[$attr:meta])*
215 $name:ident, $idx_limit:literal;
216 $(($enc_idx:literal, $enc_ty:ident, $enc_field:ident),)*
217 ) => {
218 $(#[$attr])*
219 #[derive(Debug, Clone)]
220 pub struct $name<$($enc_ty,)*> {
221 cur_idx: usize,
222 $($enc_field: $enc_ty,)*
223 }
224
225 impl<$($enc_ty,)*> $name<$($enc_ty,)*> {
226 pub const fn new($($enc_field: $enc_ty,)*) -> Self {
228 Self { cur_idx: 0, $($enc_field,)* }
229 }
230 }
231
232 impl<$($enc_ty: Encoder,)*> Encoder for $name<$($enc_ty,)*> {
233 #[inline]
234 fn current_chunk(&self) -> &[u8] {
235 match self.cur_idx {
236 $($enc_idx => self.$enc_field.current_chunk(),)*
237 _ => &[],
238 }
239 }
240
241 #[inline]
242 fn advance(&mut self) -> bool {
243 match self.cur_idx {
244 $(
245 $enc_idx => {
246 if $enc_idx == $idx_limit - 1 {
248 return self.$enc_field.advance()
249 }
250 if !self.$enc_field.advance() {
252 self.cur_idx += 1;
253 }
254 true
255 }
256 )*
257 _ => false,
258 }
259 }
260 }
261
262 impl<$($enc_ty,)*> ExactSizeEncoder for $name<$($enc_ty,)*>
263 where
264 $($enc_ty: Encoder + ExactSizeEncoder,)*
265 {
266 #[inline]
267 fn len(&self) -> usize {
268 0 $(+ self.$enc_field.len())*
269 }
270 }
271 };
272}
273
274define_encoder_n! {
275 Encoder2, 2;
277 (0, A, enc_1), (1, B, enc_2),
278}
279
280define_encoder_n! {
281 Encoder3, 3;
283 (0, A, enc_1), (1, B, enc_2), (2, C, enc_3),
284}
285
286define_encoder_n! {
287 Encoder4, 4;
289 (0, A, enc_1), (1, B, enc_2),
290 (2, C, enc_3), (3, D, enc_4),
291}
292
293define_encoder_n! {
294 Encoder6, 6;
296 (0, A, enc_1), (1, B, enc_2), (2, C, enc_3),
297 (3, D, enc_4), (4, E, enc_5), (5, F, enc_6),
298}