1use super::{error::EncodeError, DataView, Format, Write, ExtensionType};
2use crate::{BigInt, BigNumber, JSON, Context};
3use byteorder::{BigEndian, WriteBytesExt};
4use core::hash::Hash;
5use std::{collections::BTreeMap, io::Write as StdioWrite};
6
7#[derive(Debug)]
8pub struct WriteEncoder {
9 pub(crate) context: Context,
10 pub(crate) view: DataView,
11}
12
13impl WriteEncoder {
14 pub fn new(buf: &[u8], context: Context) -> Self {
15 Self {
16 context: context.clone(),
17 view: DataView::new(buf, context).expect("Error creating new data view"),
18 }
19 }
20
21 pub fn get_buffer(&self) -> Vec<u8> {
22 self.view.get_buffer()
23 }
24
25 pub fn write_negative_fixed_int(&mut self, value: i8) -> Result<(), EncodeError> {
26 assert!(-31 <= value && value <= 0);
28 Format::set_format(self, Format::NegativeFixInt(value))
29 .map_err(|e| EncodeError::FormatWriteError(e.to_string()))
30 }
31
32 pub fn write_positive_fixed_int(&mut self, value: u8) -> Result<(), EncodeError> {
33 assert!(value < 128);
34 Format::set_format(self, Format::PositiveFixInt(value))
35 .map_err(|e| EncodeError::FormatWriteError(e.to_string()))
36 }
37
38 #[doc(hidden)]
43 pub fn write_u64(&mut self, value: &u64) -> Result<(), EncodeError> {
44 let val = *value;
45 if val < 1 << 7 {
46 Ok(self.write_positive_fixed_int(val as u8)?)
47 } else if val <= u8::MAX as u64 {
48 Format::set_format(self, Format::Uint8)?;
49 Ok(WriteBytesExt::write_u8(self, val as u8)?)
50 } else if val <= u16::MAX as u64 {
51 Format::set_format(self, Format::Uint16)?;
52 Ok(WriteBytesExt::write_u16::<BigEndian>(self, val as u16)?)
53 } else if val <= u32::MAX as u64 {
54 Format::set_format(self, Format::Uint32)?;
55 Ok(WriteBytesExt::write_u32::<BigEndian>(self, val as u32)?)
56 } else {
57 Format::set_format(self, Format::Uint64)?;
58 Ok(WriteBytesExt::write_u64::<BigEndian>(self, val as u64)?)
59 }
60 }
61
62 #[doc(hidden)]
68 pub fn write_i64(&mut self, value: &i64) -> Result<(), EncodeError> {
69 let val = *value;
70
71 if val >= 0 && val < 1 << 7 {
72 Ok(self.write_positive_fixed_int(val as u8)?)
73 } else if val < 0 && val >= -(1 << 5) {
74 Ok(self.write_negative_fixed_int(val as i8)?)
75 } else if val <= i8::MAX as i64 && val >= i8::MIN as i64 {
76 Format::set_format(self, Format::Int8)?;
77 Ok(WriteBytesExt::write_i8(self, val as i8)?)
78 } else if val <= i16::MAX as i64 && val >= i16::MIN as i64 {
79 Format::set_format(self, Format::Int16)?;
80 Ok(WriteBytesExt::write_i16::<BigEndian>(self, val as i16)?)
81 } else if val <= i32::MAX as i64 && val >= i32::MIN as i64 {
82 Format::set_format(self, Format::Int32)?;
83 Ok(WriteBytesExt::write_i32::<BigEndian>(self, val as i32)?)
84 } else {
85 Format::set_format(self, Format::Int64)?;
86 Ok(WriteBytesExt::write_i64::<BigEndian>(self, val as i64)?)
87 }
88 }
89}
90
91impl StdioWrite for WriteEncoder {
92 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
93 self.view.buffer.write(buf)
94 }
95
96 fn flush(&mut self) -> std::io::Result<()> {
97 self.view.buffer.flush()
98 }
99}
100
101impl Write for WriteEncoder {
102 fn write_nil(&mut self) -> Result<(), EncodeError> {
103 Format::set_format(self, Format::Nil).map_err(|e| EncodeError::NilWriteError(e.to_string()))
104 }
105
106 fn write_bool(&mut self, value: &bool) -> Result<(), EncodeError> {
107 let format = if *value { Format::True } else { Format::False };
108 Format::set_format(self, format).map_err(|e| EncodeError::BooleanWriteError(e.to_string()))
109 }
110
111 fn write_i8(&mut self, value: &i8) -> Result<(), EncodeError> {
112 self.write_i64(&(*value as i64))
113 .map_err(|e| EncodeError::Int8WriteError(e.to_string()))
114 }
115
116 fn write_i16(&mut self, value: &i16) -> Result<(), EncodeError> {
117 self.write_i64(&(*value as i64))
118 .map_err(|e| EncodeError::Int16WriteError(e.to_string()))
119 }
120
121 fn write_i32(&mut self, value: &i32) -> Result<(), EncodeError> {
122 self.write_i64(&(*value as i64))
123 .map_err(|e| EncodeError::Int32WriteError(e.to_string()))
124 }
125
126 fn write_u8(&mut self, value: &u8) -> Result<(), EncodeError> {
127 self.write_u64(&(*value as u64))
128 .map_err(|e| EncodeError::Uint8WriteError(e.to_string()))
129 }
130
131 fn write_u16(&mut self, value: &u16) -> Result<(), EncodeError> {
132 self.write_u64(&(*value as u64))
133 .map_err(|e| EncodeError::Uint16WriteError(e.to_string()))
134 }
135
136 fn write_u32(&mut self, value: &u32) -> Result<(), EncodeError> {
137 self.write_u64(&(*value as u64))
138 .map_err(|e| EncodeError::Uint32WriteError(e.to_string()))
139 }
140
141 fn write_f32(&mut self, value: &f32) -> Result<(), EncodeError> {
142 Format::set_format(self, Format::Float32)?;
143 WriteBytesExt::write_f32::<BigEndian>(self, *value)
144 .map_err(|e| EncodeError::Float32WriteError(e.to_string()))
145 }
146
147 fn write_f64(&mut self, value: &f64) -> Result<(), EncodeError> {
148 Format::set_format(self, Format::Float64)?;
149 WriteBytesExt::write_f64::<BigEndian>(self, *value)
150 .map_err(|e| EncodeError::Float64WriteError(e.to_string()))
151 }
152
153 fn write_string_length(&mut self, length: &u32) -> Result<(), EncodeError> {
154 let length = *length;
155 if length < 32 {
156 Format::set_format(self, Format::FixStr(length as u8))?;
157 } else if length <= u8::MAX as u32 {
158 Format::set_format(self, Format::Str8)?;
159 WriteBytesExt::write_u8(self, length as u8)?;
160 } else if length <= u16::MAX as u32 {
161 Format::set_format(self, Format::Str16)?;
162 WriteBytesExt::write_u16::<BigEndian>(self, length as u16)?;
163 } else {
164 Format::set_format(self, Format::Str32)?;
165 WriteBytesExt::write_u32::<BigEndian>(self, length)?;
166 }
167 Ok(())
168 }
169
170 fn write_string(&mut self, value: &str) -> Result<(), EncodeError> {
171 self.write_string_length(&(value.len() as u32))?;
172 self.write_all(value.as_bytes())
173 .map_err(|e| EncodeError::StrWriteError(e.to_string()))
174 }
175
176 fn write_bytes_length(&mut self, length: &u32) -> Result<(), EncodeError> {
177 let length = *length;
178 if length <= u8::MAX as u32 {
179 Format::set_format(self, Format::Bin8)?;
180 WriteBytesExt::write_u8(self, length as u8)?;
181 } else if length <= u16::MAX as u32 {
182 Format::set_format(self, Format::Bin16)?;
183 WriteBytesExt::write_u16::<BigEndian>(self, length as u16)?;
184 } else {
185 Format::set_format(self, Format::Bin32)?;
186 WriteBytesExt::write_u32::<BigEndian>(self, length)?;
187 }
188 Ok(())
189 }
190
191 fn write_bytes(&mut self, buf: &[u8]) -> Result<(), EncodeError> {
192 if buf.is_empty() {
193 return self.write_nil();
194 }
195 self.write_bytes_length(&(buf.len() as u32))?;
196 self.write_all(buf)
197 .map_err(|e| EncodeError::BinWriteError(e.to_string()))
198 }
199
200 fn write_bigint(&mut self, value: &BigInt) -> Result<(), EncodeError> {
201 self.write_string(&value.to_string())
202 .map_err(|e| EncodeError::BigIntWriteError(e.to_string()))
203 }
204
205 fn write_bignumber(&mut self, value: &BigNumber) -> Result<(), EncodeError> {
206 self.write_string(&value.to_string())
207 .map_err(|e| EncodeError::BigIntWriteError(e.to_string()))
208 }
209
210 fn write_json(&mut self, value: &JSON::Value) -> Result<(), EncodeError> {
211 let json_str = JSON::to_string(value)?;
212 self.write_string(&json_str)
213 .map_err(|e| EncodeError::JSONWriteError(e.to_string()))
214 }
215
216 fn write_array_length(&mut self, length: &u32) -> Result<(), EncodeError> {
217 let length = *length;
218 if length < 16 {
219 Format::set_format(self, Format::FixArray(length as u8))?;
220 } else if length <= u16::MAX as u32 {
221 Format::set_format(self, Format::Array16)?;
222 WriteBytesExt::write_u16::<BigEndian>(self, length as u16)?;
223 } else {
224 Format::set_format(self, Format::Array32)?;
225 WriteBytesExt::write_u32::<BigEndian>(self, length)?;
226 }
227 Ok(())
228 }
229
230 fn write_array<T: Clone>(
231 &mut self,
232 array: &[T],
233 mut item_writer: impl FnMut(&mut Self, &T) -> Result<(), EncodeError>,
234 ) -> Result<(), EncodeError> {
235 self.write_array_length(&(array.len() as u32))?;
236 for element in array {
237 item_writer(self, element)?;
238 }
239 Ok(())
240 }
241
242 fn write_map_length(&mut self, length: &u32) -> Result<(), EncodeError> {
243 let length = *length;
244 if length < 16 {
245 Format::set_format(self, Format::FixMap(length as u8))?;
246 } else if length <= u16::MAX as u32 {
247 Format::set_format(self, Format::Map16)?;
248 WriteBytesExt::write_u16::<BigEndian>(self, length as u16)?;
249 } else {
250 Format::set_format(self, Format::Map32)?;
251 WriteBytesExt::write_u32::<BigEndian>(self, length)?;
252 }
253 Ok(())
254 }
255
256 fn write_map<K, V: Clone>(
257 &mut self,
258 map: &BTreeMap<K, V>,
259 mut key_writer: impl FnMut(&mut Self, &K) -> Result<(), EncodeError>,
260 mut val_writer: impl FnMut(&mut Self, &V) -> Result<(), EncodeError>,
261 ) -> Result<(), EncodeError>
262 where
263 K: Clone + Eq + Hash + Ord,
264 {
265 self.write_map_length(&(map.len() as u32))?;
266 let keys: Vec<_> = map.keys().into_iter().collect();
267 for key in keys {
268 let value = &map[key];
269 key_writer(self, key)?;
270 val_writer(self, value)?;
271 }
272 Ok(())
273 }
274
275 fn write_ext_generic_map<K, V: Clone>(
276 &mut self,
277 map: &BTreeMap<K, V>,
278 mut key_writer: impl FnMut(&mut Self, &K) -> Result<(), EncodeError>,
279 mut val_writer: impl FnMut(&mut Self, &V) -> Result<(), EncodeError>,
280 ) -> Result<(), EncodeError>
281 where
282 K: Clone + Eq + Hash + Ord,
283 {
284 let mut encoder = WriteEncoder::new(&[], self.context.clone());
285 encoder.write_map(map, key_writer, val_writer)?;
286
287 let buf = encoder.get_buffer();
288 let bytelength = buf.len();
289
290 if bytelength <= u8::MAX as usize {
292 Format::set_format(self, Format::Ext8)?;
293 WriteBytesExt::write_u8(self, bytelength.try_into().unwrap())?;
294 } else if bytelength <= u16::MAX as usize {
295 Format::set_format(self, Format::Ext16)?;
296 WriteBytesExt::write_u16::<BigEndian>(self, bytelength.try_into().unwrap())?;
297 } else {
298 Format::set_format(self, Format::Ext32)?;
299 WriteBytesExt::write_u32::<BigEndian>(self, bytelength.try_into().unwrap())?;
300 }
301
302 WriteBytesExt::write_u8(self, ExtensionType::GenericMap.to_u8())?;
304
305 self.view.buffer.write_all(&buf)?;
307
308 Ok(())
309 }
310
311 fn write_nullable_bool(&mut self, value: &Option<bool>) -> Result<(), EncodeError> {
312 match value {
313 None => Write::write_nil(self),
314 Some(v) => Write::write_bool(self, v),
315 }
316 }
317
318 fn write_nullable_i8(&mut self, value: &Option<i8>) -> Result<(), EncodeError> {
319 match value {
320 None => Write::write_nil(self),
321 Some(v) => Write::write_i8(self, v),
322 }
323 }
324
325 fn write_nullable_i16(&mut self, value: &Option<i16>) -> Result<(), EncodeError> {
326 match value {
327 None => Write::write_nil(self),
328 Some(v) => Write::write_i16(self, v),
329 }
330 }
331
332 fn write_nullable_i32(&mut self, value: &Option<i32>) -> Result<(), EncodeError> {
333 match value {
334 None => Write::write_nil(self),
335 Some(v) => Write::write_i32(self, v),
336 }
337 }
338
339 fn write_nullable_u8(&mut self, value: &Option<u8>) -> Result<(), EncodeError> {
340 match value {
341 None => Write::write_nil(self),
342 Some(v) => Write::write_u8(self, v),
343 }
344 }
345
346 fn write_nullable_u16(&mut self, value: &Option<u16>) -> Result<(), EncodeError> {
347 match value {
348 None => Write::write_nil(self),
349 Some(v) => Write::write_u16(self, v),
350 }
351 }
352
353 fn write_nullable_u32(&mut self, value: &Option<u32>) -> Result<(), EncodeError> {
354 match value {
355 None => Write::write_nil(self),
356 Some(v) => Write::write_u32(self, v),
357 }
358 }
359
360 fn write_nullable_f32(&mut self, value: &Option<f32>) -> Result<(), EncodeError> {
361 match value {
362 None => Write::write_nil(self),
363 Some(v) => Write::write_f32(self, v),
364 }
365 }
366
367 fn write_nullable_f64(&mut self, value: &Option<f64>) -> Result<(), EncodeError> {
368 match value {
369 None => Write::write_nil(self),
370 Some(v) => Write::write_f64(self, v),
371 }
372 }
373
374 fn write_nullable_string(&mut self, value: &Option<String>) -> Result<(), EncodeError> {
375 match value {
376 None => Write::write_nil(self),
377 Some(s) => Write::write_string(self, s),
378 }
379 }
380
381 fn write_nullable_bytes(&mut self, value: &Option<Vec<u8>>) -> Result<(), EncodeError> {
382 match value {
383 None => Write::write_nil(self),
384 Some(bytes) => Write::write_bytes(self, bytes),
385 }
386 }
387
388 fn write_nullable_bigint(&mut self, value: &Option<BigInt>) -> Result<(), EncodeError> {
389 match value {
390 None => Write::write_nil(self),
391 Some(bigint) => Write::write_bigint(self, bigint),
392 }
393 }
394
395 fn write_nullable_bignumber(&mut self, value: &Option<BigNumber>) -> Result<(), EncodeError> {
396 match value {
397 None => Write::write_nil(self),
398 Some(bignumber) => Write::write_bignumber(self, bignumber)
399 }
400 }
401
402 fn write_nullable_json(&mut self, value: &Option<JSON::Value>) -> Result<(), EncodeError> {
403 match value {
404 None => Write::write_nil(self),
405 Some(json) => Write::write_json(self, json),
406 }
407 }
408
409 fn write_nullable_array<T: Clone>(
410 &mut self,
411 opt_array: &Option<Vec<T>>,
412 item_writer: impl FnMut(&mut Self, &T) -> Result<(), EncodeError>,
413 ) -> Result<(), EncodeError> {
414 match opt_array {
415 None => Write::write_nil(self),
416 Some(array) => Write::write_array(self, array, item_writer),
417 }
418 }
419
420 fn write_nullable_map<K, V: Clone>(
421 &mut self,
422 opt_map: &Option<BTreeMap<K, V>>,
423 key_writer: impl FnMut(&mut Self, &K) -> Result<(), EncodeError>,
424 val_writer: impl FnMut(&mut Self, &V) -> Result<(), EncodeError>,
425 ) -> Result<(), EncodeError>
426 where
427 K: Clone + Eq + Hash + Ord,
428 {
429 match opt_map {
430 None => Write::write_nil(self),
431 Some(map) => Write::write_map(self, map, key_writer, val_writer),
432 }
433 }
434
435 fn write_nullable_ext_generic_map<K, V: Clone>(
436 &mut self,
437 opt_map: &Option<BTreeMap<K, V>>,
438 key_writer: impl FnMut(&mut Self, &K) -> Result<(), EncodeError>,
439 val_writer: impl FnMut(&mut Self, &V) -> Result<(), EncodeError>,
440 ) -> Result<(), EncodeError>
441 where
442 K: Clone + Eq + Hash + Ord,
443 {
444 match opt_map {
445 None => Write::write_nil(self),
446 Some(map) => Write::write_ext_generic_map(self, map, key_writer, val_writer),
447 }
448 }
449
450 fn context(&mut self) -> &mut Context {
451 &mut self.context
452 }
453}