protocol/
hint.rs

1use std::collections::HashMap;
2
3pub type FieldIndex = usize;
4
5/// Hints given when reading parcels.
6#[derive(Clone, Debug, PartialEq)]
7pub struct Hints {
8    pub current_field_index: Option<FieldIndex>,
9    /// The fields for which a length prefix
10    /// was already present earlier in the layout.
11    pub known_field_lengths: HashMap<FieldIndex, FieldLength>,
12}
13
14/// Information about the length of a field.
15#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
16pub struct FieldLength {
17    pub length: usize,
18    pub kind: LengthPrefixKind,
19}
20
21/// Specifies what kind of data the length prefix captures.
22#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
23pub enum LengthPrefixKind {
24    /// The length prefix stores the total number of bytes making up another field.
25    Bytes,
26    /// The length prefix stores the total number of elements inside another field.
27    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    /// Gets the length of the field currently being
42    /// read, if known.
43    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
48/// Helpers for the `protocol-derive` crate.
49mod protocol_derive_helpers {
50    use super::*;
51
52    impl Hints {
53        // Sets hints indicating a new set of fields are beginning.
54        #[doc(hidden)]
55        pub fn begin_fields(&mut self) {
56            self.current_field_index = Some(0);
57        }
58
59        // Updates the hints to indicate a field was just read.
60        #[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        // Sets the length of a variable-sized field by its 0-based index.
67        #[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