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