epee_encoding/
marker.rs

1/// This module contains a [`Marker`] which is appended before each value to tell you the type.
2use crate::Error;
3
4/// The inner marker just telling you the type.
5#[derive(Debug, Clone, Eq, PartialEq)]
6pub enum InnerMarker {
7    I64,
8    I32,
9    I16,
10    I8,
11    U64,
12    U32,
13    U16,
14    U8,
15    F64,
16    String,
17    Bool,
18    Object,
19}
20
21/// A marker appended before Epee values which tell you the type of the field and if
22/// its a sequence.
23#[derive(Debug, Clone, Eq, PartialEq)]
24pub struct Marker {
25    pub inner_marker: InnerMarker,
26    pub is_seq: bool,
27}
28
29impl Marker {
30    pub(crate) const fn new(inner_marker: InnerMarker) -> Self {
31        Marker {
32            inner_marker,
33            is_seq: false,
34        }
35    }
36    pub const fn into_seq(self) -> Self {
37        if self.is_seq {
38            panic!("Sequence of sequence not allowed!");
39        }
40        if matches!(self.inner_marker, InnerMarker::U8) {
41            return Marker {
42                inner_marker: InnerMarker::String,
43                is_seq: false,
44            };
45        }
46
47        Marker {
48            inner_marker: self.inner_marker,
49            is_seq: true,
50        }
51    }
52
53    pub const fn as_u8(&self) -> u8 {
54        let marker_val = match self.inner_marker {
55            InnerMarker::I64 => 1,
56            InnerMarker::I32 => 2,
57            InnerMarker::I16 => 3,
58            InnerMarker::I8 => 4,
59            InnerMarker::U64 => 5,
60            InnerMarker::U32 => 6,
61            InnerMarker::U16 => 7,
62            InnerMarker::U8 => 8,
63            InnerMarker::F64 => 9,
64            InnerMarker::String => 10,
65            InnerMarker::Bool => 11,
66            InnerMarker::Object => 12,
67        };
68
69        if self.is_seq {
70            marker_val | 0x80
71        } else {
72            marker_val
73        }
74    }
75}
76
77impl TryFrom<u8> for Marker {
78    type Error = Error;
79
80    fn try_from(mut value: u8) -> Result<Self, Self::Error> {
81        let is_seq = value & 0x80 > 0;
82
83        if is_seq {
84            value ^= 0x80;
85        }
86
87        let inner_marker = match value {
88            1 => InnerMarker::I64,
89            2 => InnerMarker::I32,
90            3 => InnerMarker::I16,
91            4 => InnerMarker::I8,
92            5 => InnerMarker::U64,
93            6 => InnerMarker::U32,
94            7 => InnerMarker::U16,
95            8 => InnerMarker::U8,
96            9 => InnerMarker::F64,
97            10 => InnerMarker::String,
98            11 => InnerMarker::Bool,
99            12 => InnerMarker::Object,
100            _ => return Err(Error::Format("Unknown value Marker")),
101        };
102
103        Ok(Marker {
104            inner_marker,
105            is_seq,
106        })
107    }
108}