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
use std::collections::HashMap;
pub type FieldIndex = usize;
#[derive(Clone, Debug, PartialEq)]
pub struct Hints {
pub current_field_index: Option<FieldIndex>,
pub known_field_lengths: HashMap<FieldIndex, FieldLength>,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct FieldLength {
pub length: usize,
pub kind: LengthPrefixKind,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum LengthPrefixKind {
Bytes,
Elements,
}
impl Default for Hints {
fn default() -> Self {
Hints {
current_field_index: None,
known_field_lengths: HashMap::new(),
}
}
}
impl Hints {
pub fn current_field_length(&self) -> Option<FieldLength> {
self.current_field_index.and_then(|index| self.known_field_lengths.get(&index)).cloned()
}
}
mod protocol_derive_helpers {
use super::*;
impl Hints {
#[doc(hidden)]
pub fn begin_fields(&mut self) {
self.current_field_index = Some(0);
}
#[doc(hidden)]
pub fn next_field(&mut self) {
*self.current_field_index.as_mut()
.expect("cannot increment next field when not in a struct")+= 1;
}
#[doc(hidden)]
pub fn set_field_length(&mut self,
field_index: FieldIndex,
length: usize,
kind: LengthPrefixKind) {
self.known_field_lengths.insert(field_index, FieldLength { kind, length });
}
}
}