1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
|
//! Encoding: writing protocol values into a byte stream.
use crate::codec::error::Result;
use crate::context::Context;
use std::{
collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
io::Write,
};
macro_rules! impl_encode {
(u8) => {
impl<Data> Encode<Data> for u8 {
/// write number using big endian
fn encode(&self, buffer: &mut dyn Write, _: &Context<Data>) -> Result<usize> {
let size = buffer.write(&self.to_be_bytes())?;
Ok(size)
}
/// write raw bytes
fn encode_slice(
slice: &[Self],
buffer: &mut dyn Write,
_: &Context<Data>,
) -> Result<usize> {
buffer.write(slice).map_err(Into::into)
}
}
};
($t: ty) => {
impl<Data> Encode<Data> for $t {
/// write number using big endian
fn encode(&self, buffer: &mut dyn Write, _: &Context<Data>) -> Result<usize> {
let size = buffer.write(&self.to_be_bytes())?;
Ok(size)
}
fn encode_slice(
slice: &[Self],
buffer: &mut dyn Write,
_: &Context<Data>,
) -> Result<usize> {
let len = buffer.write(
&slice
.iter()
.flat_map(|n| n.to_be_bytes())
.collect::<Box<[u8]>>(),
)?;
Ok(len)
}
}
};
}
macro_rules! impl_encode_tuples {
($($generic: ident),+) => {
impl<Data, $($generic),+> Encode<Data> for ($($generic,)+)
where
$($generic: Encode<Data>),+
{
#[allow(non_snake_case)]
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
let ($($generic,)+): &($($generic,)+) = self;
let mut len = 0;
$(len += $generic.encode(buffer, ctx)?;)+
Ok(len)
}
}
};
}
/// Write a value into a byte stream
pub trait Encode<Data> {
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize>;
fn encode_slice(slice: &[Self], buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize>
where
Self: Sized,
{
let mut len = 0;
for item in slice {
len += item.encode(buffer, ctx)?;
}
Ok(len)
}
}
// ~ Encode arrays
impl<Data, T: Encode<Data>> Encode<Data> for Vec<T> {
/// Encode each element of Vec
/// use `CountPrefix` to prefix the vector with number of elements
/// use `LenPrefix` to prefix the vector with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
T::encode_slice(self, buffer, ctx)
}
}
impl<Data, T: Encode<Data>> Encode<Data> for VecDeque<T> {
/// Encode each element of VecDeque
/// use `CountPrefix` to prefix the VecDeque with number of elements
/// use `LenPrefix` to prefix the VecDeque with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
let (front, _) = self.as_slices();
T::encode_slice(front, buffer, ctx)
}
}
impl<Data, T: Encode<Data>> Encode<Data> for LinkedList<T>
where
T: Clone,
{
/// Encode each element of LinkedList (use clone..)
/// use `CountPrefix` to prefix the LinkedList with number of elements
/// use `LenPrefix` to prefix the LinkedList with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
let mut view = Vec::with_capacity(self.len());
view.extend(self.iter().cloned());
T::encode_slice(&view, buffer, ctx)
}
}
// ~ Encode slices
impl<Data, T: Encode<Data>> Encode<Data> for &[T] {
/// Encode each element of slice (use clone..)
/// use `CountPrefix` to prefix the slice with number of elements
/// use `LenPrefix` to prefix the slice with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
T::encode_slice(self, buffer, ctx)
}
}
impl<Data, T: Encode<Data>, const S: usize> Encode<Data> for [T; S] {
/// Encode each element of slice (use clone..)
/// use `CountPrefix` to prefix the slice with number of elements
/// use `LenPrefix` to prefix the slice with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
T::encode_slice(self, buffer, ctx)
}
}
impl<Data, T: Encode<Data>> Encode<Data> for [T] {
/// Encode each element of slice (use clone..)
/// use `CountPrefix` to prefix the slice with number of elements
/// use `LenPrefix` to prefix the slice with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
T::encode_slice(self, buffer, ctx)
}
}
// ~ Encode set
impl<Data, T: Encode<Data>> Encode<Data> for HashSet<T>
where
T: Clone,
{
/// Encode each element of HashSet (use clone..)
/// use `CountPrefix` to prefix the HashSet with number of elements
/// use `LenPrefix` to prefix the HashSet with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
let mut view = Vec::with_capacity(self.len());
view.extend(self.iter().cloned());
T::encode_slice(&view, buffer, ctx)
}
}
impl<Data, T: Encode<Data>> Encode<Data> for BTreeSet<T>
where
T: Clone,
{
/// Encode each element of BTreeSet (use clone..)
/// use `CountPrefix` to prefix the BTreeSet with number of elements
/// use `LenPrefix` to prefix the BTreeSet with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
let mut view = Vec::with_capacity(self.len());
view.extend(self.iter().cloned());
T::encode_slice(&view, buffer, ctx)
}
}
// ~ Encode misc
impl<Data, T> Encode<Data> for BinaryHeap<T>
where
T: Encode<Data>,
{
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
T::encode_slice(self.as_slice(), buffer, ctx)
}
}
// ~ Encode maps
impl<Data, K, V> Encode<Data> for HashMap<K, V>
where
K: Encode<Data> + Clone,
V: Encode<Data> + Clone,
{
/// Encode each element of HashMap (use clone..)
/// use `CountPrefix` to prefix the HashMap with number of pairs
/// use `LenPrefix` to prefix the HashMap with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
let slice: Vec<(K, V)> = self.clone().into_iter().collect();
<(K, V) as Encode<Data>>::encode_slice(&slice, buffer, ctx)
}
}
impl<Data, K, V> Encode<Data> for BTreeMap<K, V>
where
K: Encode<Data> + Clone,
V: Encode<Data> + Clone,
{
/// Encode each element of BTreeMap (use clone..)
/// use `CountPrefix` to prefix the BTreeMap with number of pairs
/// use `LenPrefix` to prefix the BTreeMap with encoded byte size
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
let slice: Vec<(K, V)> = self.clone().into_iter().collect();
<(K, V) as Encode<Data>>::encode_slice(&slice, buffer, ctx)
}
}
// ~ Encode string
impl<Data> Encode<Data> for String {
/// Encode the string using utf8
/// use `CountPrefix` to prefix the string with char length
/// use `LenPrefix` to prefix the string with utf8 bytes length
fn encode(&self, buffer: &mut dyn Write, _: &Context<Data>) -> Result<usize> {
let utf8 = self.as_bytes();
buffer.write_all(utf8)?;
Ok(utf8.len())
}
}
impl<Data> Encode<Data> for &str {
/// Encode the string using utf8
/// use `CountPrefix` to prefix the string with char length
/// use `LenPrefix` to prefix the string with utf8 bytes length
fn encode(&self, buffer: &mut dyn Write, _: &Context<Data>) -> Result<usize> {
let utf8 = self.as_bytes();
buffer.write_all(utf8)?;
Ok(utf8.len())
}
}
impl<Data, T: Encode<Data>> Encode<Data> for Option<T> {
/// Encode `T` if Some(T) or do nothing if None
fn encode(&self, buffer: &mut dyn Write, ctx: &Context<Data>) -> Result<usize> {
match self {
Some(val) => {
let size = val.encode(buffer, ctx)?;
Ok(size)
}
None => Ok(0),
}
}
}
// ~ Encode primitive
impl<Data> Encode<Data> for bool {
fn encode(&self, buffer: &mut dyn Write, _: &Context<Data>) -> Result<usize> {
let size = buffer.write(&[*self as u8])?;
Ok(size)
}
fn encode_slice(slice: &[Self], buffer: &mut dyn Write, _: &Context<Data>) -> Result<usize>
where
Self: Sized,
{
let len = buffer.write(&slice.iter().map(|n| *n as u8).collect::<Box<[u8]>>())?;
Ok(len)
}
}
impl_encode!(u8);
impl_encode!(u16);
impl_encode!(u32);
impl_encode!(u64);
impl_encode!(u128);
impl_encode!(usize);
impl_encode!(i8);
impl_encode!(i16);
impl_encode!(i32);
impl_encode!(i64);
impl_encode!(i128);
impl_encode!(isize);
#[cfg(feature = "f16")]
impl_encode!(f16);
impl_encode!(f32);
impl_encode!(f64);
#[cfg(feature = "f128")]
impl_encode!(f128);
// ~ Encode tuple
impl<Data> Encode<Data> for () {
fn encode(&self, _: &mut dyn Write, _: &Context<Data>) -> Result<usize> {
Ok(0)
}
fn encode_slice(_: &[Self], _: &mut dyn Write, _: &Context<Data>) -> Result<usize>
where
Self: Sized,
{
Ok(0)
}
}
impl_encode_tuples!(A);
impl_encode_tuples!(A, B);
impl_encode_tuples!(A, B, C);
impl_encode_tuples!(A, B, C, D);
impl_encode_tuples!(A, B, C, D, E);
impl_encode_tuples!(A, B, C, D, E, F);
impl_encode_tuples!(A, B, C, D, E, F, G);
impl_encode_tuples!(A, B, C, D, E, F, G, H);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
impl_encode_tuples!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q);
|