1use std::collections::HashMap;
2
3pub type FieldIndex = usize;
4
5#[derive(Clone, Debug, PartialEq)]
7pub struct Hints {
8 pub skip_hint: Option<bool>,
9 pub current_field_index: Option<FieldIndex>,
10 pub known_field_lengths: HashMap<FieldIndex, FieldLength>,
13}
14
15#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
17pub struct FieldLength {
18 pub length: usize,
19 pub kind: LengthPrefixKind,
20}
21
22#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
24pub enum LengthPrefixKind {
25 Bytes,
27 Elements,
29 Pointers,
31}
32
33
34impl Default for Hints {
35 fn default() -> Self {
36 Hints {
37 skip_hint: None,
38 current_field_index: None,
39 known_field_lengths: HashMap::new(),
40 }
41 }
42}
43
44impl Hints {
45 pub fn current_field_length(&self) -> Option<FieldLength> {
48 self.current_field_index.and_then(|index| self.known_field_lengths.get(&index)).cloned()
49 }
50}
51
52mod protocol_derive_helpers {
54 use super::*;
55
56 impl Hints {
57 #[doc(hidden)]
59 pub fn begin_fields(&mut self) {
60 self.current_field_index = Some(0);
61 }
62
63 #[doc(hidden)]
65 pub fn next_field(&mut self) {
66 *self.current_field_index.as_mut()
67 .expect("cannot increment next field when not in a struct") += 1;
68 }
69
70 #[doc(hidden)]
72 pub fn set_field_length(&mut self,
73 field_index: FieldIndex,
74 length: usize,
75 kind: LengthPrefixKind) {
76 self.known_field_lengths.insert(field_index, FieldLength { kind, length });
77 }
78
79 #[doc(hidden)]
82 pub fn set_skip(&mut self, do_skip: bool) {
83 self.skip_hint = Some(do_skip);
84 }
85 }
86}
87