substrate_data/wire/binary/
writer.rs1use super::interner::Interner;
4use super::{MAGIC, NEW_STRING, VERSION, tag, varint, zigzag};
5use crate::model::value::Value;
6
7pub(crate) const START_BYTES: usize = 256;
9
10#[derive(Debug)]
21pub struct Writer {
22 out: Vec<u8>,
23 strings: Interner,
25}
26
27impl Default for Writer {
28 fn default() -> Self {
29 Self::new()
30 }
31}
32
33impl Writer {
34 #[must_use]
36 pub fn new() -> Self {
37 let mut out = Vec::with_capacity(START_BYTES);
38 out.extend_from_slice(MAGIC);
39 out.push(VERSION);
40 Writer {
41 out,
42 strings: Interner::new(),
43 }
44 }
45
46 pub fn null(&mut self) -> &mut Self {
48 self.out.push(tag::NULL);
49 self
50 }
51
52 pub fn bool(&mut self, b: bool) -> &mut Self {
54 self.out.push(if b { tag::TRUE } else { tag::FALSE });
55 self
56 }
57
58 pub fn int(&mut self, n: i64) -> &mut Self {
60 self.out.push(tag::INT);
61 varint(&mut self.out, zigzag(n));
62 self
63 }
64
65 pub fn float(&mut self, f: f64) -> &mut Self {
67 self.out.push(tag::FLOAT);
68 self.out.extend_from_slice(&f.to_le_bytes());
69 self
70 }
71
72 pub fn float32(&mut self, f: f32) -> &mut Self {
74 self.out.push(tag::FLOAT32);
75 self.out.extend_from_slice(&f.to_le_bytes());
76 self
77 }
78
79 pub fn floats(&mut self, items: &[f64]) -> &mut Self {
82 let narrow = crate::frame::floats::fits_f32(items);
83 self.out
84 .push(if narrow { tag::FLOATS32 } else { tag::FLOATS });
85 varint(&mut self.out, items.len() as u64);
86 if narrow {
87 crate::frame::floats::put_narrow(&mut self.out, items);
88 } else {
89 crate::frame::floats::put_wide(&mut self.out, items);
90 }
91 self
92 }
93
94 pub fn floats32(&mut self, items: &[f32]) -> &mut Self {
96 self.out.push(tag::FLOATS32);
97 varint(&mut self.out, items.len() as u64);
98 crate::frame::floats::put_f32s(&mut self.out, items);
99 self
100 }
101
102 pub fn str(&mut self, s: &str) -> &mut Self {
104 self.out.push(tag::STR);
105 self.string(s);
106 self
107 }
108
109 pub fn bytes(&mut self, b: &[u8]) -> &mut Self {
111 self.out.push(tag::BYTES);
112 varint(&mut self.out, b.len() as u64);
113 self.out.extend_from_slice(b);
114 self
115 }
116
117 pub fn list(&mut self, len: usize) -> &mut Self {
119 self.out.push(tag::LIST);
120 varint(&mut self.out, len as u64);
121 self
122 }
123
124 pub fn ints(&mut self, items: impl ExactSizeIterator<Item = i64>) -> &mut Self {
126 self.out.push(tag::INTS);
127 varint(&mut self.out, items.len() as u64);
128 for n in items {
129 varint(&mut self.out, zigzag(n));
130 }
131 self
132 }
133
134 pub(crate) fn stream_body(&mut self, len: usize, items: &[u8]) -> &mut Self {
136 let mut count = Vec::new();
137 varint(&mut count, len as u64);
138 self.out.push(tag::STREAM);
139 let body = u32::try_from(count.len() + items.len()).unwrap_or(u32::MAX);
140 self.out.extend_from_slice(&body.to_le_bytes());
141 self.out.extend_from_slice(&count);
142 self.out.extend_from_slice(items);
143 self
144 }
145
146 pub(crate) fn body() -> Self {
148 Writer {
149 out: Vec::with_capacity(START_BYTES),
150 strings: Interner::new(),
151 }
152 }
153
154 pub fn map(&mut self, len: usize) -> &mut Self {
156 self.out.push(tag::MAP);
157 varint(&mut self.out, len as u64);
158 self
159 }
160
161 pub fn key(&mut self, k: &str) -> &mut Self {
163 self.string(k);
164 self
165 }
166
167 pub fn value(&mut self, v: &Value) -> &mut Self {
169 match v {
170 Value::Null => self.null(),
171 Value::Bool(b) => self.bool(*b),
172 Value::Int(n) => self.int(*n),
173 Value::Float(f) => self.float(*f),
174 Value::Str(s) => self.str(s),
175 Value::List(items) => {
176 self.list(items.len());
177 for item in items {
178 self.value(item);
179 }
180 self
181 }
182 Value::Map(map) => {
183 self.map(map.len());
184 for (key, item) in map.iter() {
185 self.string(key);
186 self.value(item);
187 }
188 self
189 }
190 Value::Ref(r) => {
191 self.out.push(tag::REF);
192 self.string(r.kind.as_str());
193 self.string(r.id.as_str());
194 self
195 }
196 Value::Bytes(b) => self.bytes(b),
197 }
198 }
199
200 #[must_use]
202 pub fn finish(self) -> Vec<u8> {
203 self.out
204 }
205
206 fn string(&mut self, s: &str) {
208 if let Some(i) = self.strings.find(&self.out, s) {
209 varint(&mut self.out, (i as u64) << 1);
210 return;
211 }
212 varint(&mut self.out, ((s.len() as u64) << 1) | NEW_STRING);
213 let at = self.out.len();
214 self.out.extend_from_slice(s.as_bytes());
215 self.strings.add(&self.out, s, at);
216 }
217}