1use std::collections::HashMap;
2
3pub type FieldIndex = usize;
4
5#[derive(Clone, Debug, PartialEq)]
7pub struct Hints {
8 pub current_field_index: Option<FieldIndex>,
9 pub known_field_lengths: HashMap<FieldIndex, FieldLength>,
12}
13
14#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
16pub struct FieldLength {
17 pub length: usize,
18 pub kind: LengthPrefixKind,
19}
20
21#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
23pub enum LengthPrefixKind {
24 Bytes,
26 Elements,
28}
29
30
31impl Default for Hints {
32 fn default() -> Self {
33 Hints {
34 current_field_index: None,
35 known_field_lengths: HashMap::new(),
36 }
37 }
38}
39
40impl Hints {
41 pub fn current_field_length(&self) -> Option<FieldLength> {
44 self.current_field_index.and_then(|index| self.known_field_lengths.get(&index)).cloned()
45 }
46}
47
48mod protocol_derive_helpers {
50 use super::*;
51
52 impl Hints {
53 #[doc(hidden)]
55 pub fn begin_fields(&mut self) {
56 self.current_field_index = Some(0);
57 }
58
59 #[doc(hidden)]
61 pub fn next_field(&mut self) {
62 *self.current_field_index.as_mut()
63 .expect("cannot increment next field when not in a struct")+= 1;
64 }
65
66 #[doc(hidden)]
68 pub fn set_field_length(&mut self,
69 field_index: FieldIndex,
70 length: usize,
71 kind: LengthPrefixKind) {
72 self.known_field_lengths.insert(field_index, FieldLength { kind, length });
73 }
74 }
75}
76