1pub mod macros;
2
3use std::collections::HashMap;
4use std::default::Default;
5
6use bytes::{Bytes};
7
8#[derive(Default)]
9pub struct DynamicMessage {
10 inner: HashMap<u64, DynamicMessageNode>,
11}
12
13impl DynamicMessage {
14 pub fn new() -> Self {
15 Self::default()
16 }
17
18 pub fn encode(self) -> Bytes {
19 let mut encoder = DynamicMessageEncoder::new();
20
21 self._encode(&mut encoder);
22
23 encoder.into_bytes()
24 }
25
26 pub fn encode_to_vec(self) -> Vec<u8> {
27 let mut encoder = DynamicMessageEncoder::new();
28
29 self._encode(&mut encoder);
30
31 encoder.into_vec()
32 }
33
34 fn _encode(self,encoder: &mut DynamicMessageEncoder) {
35 for (id, msg) in self.inner {
36 let key = id << 3;
37
38 match msg {
39 DynamicMessageNode::I64(val) => {
40 encoder.put_uvarint(key);
41 encoder.put_svarint(val)
42 }
43 DynamicMessageNode::U64(val) => {
44 encoder.put_uvarint(key);
45 encoder.put_uvarint(val);
46 }
47 DynamicMessageNode::F32(val) => {
48 encoder.put_uvarint(key | 5);
49 encoder.put_u32_bits(val.to_bits())
50 }
51 DynamicMessageNode::F64(val) => {
52 encoder.put_uvarint(key | 1);
53 encoder.put_u64_bits(val.to_bits());
54 }
55 DynamicMessageNode::RepeatU64(vec) => {
56 for val in vec {
57 encoder.put_uvarint(key);
58 encoder.put_uvarint(val);
59 }
60 }
61 DynamicMessageNode::Bytes(b) => {
62 encoder.put_uvarint(key | 2);
63 encoder.put_uvarint(b.len() as _);
64 encoder.buf.extend(b);
65 }
66 }
67 }
68 }
69
70 pub fn set<M: Into<DynamicMessageNode>>(&mut self, k: u64, v: M) {
71 self.inner.insert(k, v.into());
72 }
73}
74
75struct DynamicMessageEncoder {
76 buf: Vec<u8>,
77}
78
79impl DynamicMessageEncoder {
80 const MAX_VARINT_LEN64: usize = 10;
83
84 pub fn new() -> Self {
85 Self {
86 buf: Vec::new(),
87 }
88 }
89
90 pub fn put_uvarint(&mut self, v: u64) {
91 let mut b = [0; Self::MAX_VARINT_LEN64];
92 let n = _put_uvarint(&mut b, v);
93 self.buf.extend(&b[..n]);
94 }
95
96 pub fn put_svarint(&mut self, v: i64) {
97 self.put_uvarint((v as u64) << 1 ^ ((v >> 63) as u64))
98 }
99
100 pub fn put_u32_bits(&mut self, v: u32) {
101 self.buf.extend(v.to_le_bytes())
102 }
103
104 pub fn put_u64_bits(&mut self, v: u64) {
105 self.buf.extend(v.to_le_bytes())
106 }
107
108 pub fn into_bytes(self) -> Bytes {
109 Bytes::from(self.buf)
110 }
111
112 pub fn into_vec(self) -> Vec<u8> {
113 self.buf
114 }
115}
116
117fn _put_uvarint(buf: &mut [u8], mut x: u64) -> usize {
118 let mut i = 0;
119 while x >= 0x80 {
120 buf[i] = (x as u8) | 0x80;
121 x >>= 7;
122 i += 1;
123 }
124 buf[i] = x as u8;
125 i + 1
126}
127
128pub enum DynamicMessageNode {
129 I64(i64),
130 U64(u64),
131 F32(f32),
132 F64(f64),
133 Bytes(Bytes),
134 RepeatU64(Vec<u64>),
135}
136
137impl From<bool> for DynamicMessageNode {
138 fn from(val: bool) -> Self {
139 Self::U64(if val { 1 } else { 0 })
140 }
141}
142
143impl From<String> for DynamicMessageNode {
144 fn from(s: String) -> Self {
145 Self::Bytes(s.into())
146 }
147}
148
149impl From<DynamicMessage> for DynamicMessageNode {
150 fn from(msg: DynamicMessage) -> Self {
151 let b = msg.encode();
152 Self::Bytes(b)
153 }
154}
155
156macro_rules! into_node_impl {
157 ($($x:ty as $variant:ident);* $(;)?) => {
158 $(
159 impl From<$x> for DynamicMessageNode {
160 fn from(val: $x) -> Self {
161 Self::$variant(val as _) }
163 }
164 )*
165 };
166}
167
168into_node_impl! {
169 i32 as I64;
170 u32 as U64;
171 i64 as I64;
172 u64 as U64;
173 f32 as F32;
174 f64 as F64;
175 Bytes as Bytes;
176 Vec<u64> as RepeatU64;
177}
178
179#[cfg(test)]
180mod tests {
181 use crate::dynamic_message;
182
183 #[test]
184 fn message() {
185 let msg = dynamic_message! {
186 1 => 23u32,
187 }
188 .encode();
189
190 assert_eq!(*msg, [8, 23]);
191 }
192}