1use crate::{Ext, Float, Int, Value};
2use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
3use std::io::Result;
4use std::io::{Read, Write};
5
6pub trait ReadFrom: Sized {
7 fn read_from<T: Read>(source: &mut T) -> Result<Self>;
8}
9
10pub trait WriteTo {
11 fn write_to<T: Write>(&self, sink: &mut T) -> Result<()>;
12}
13
14impl WriteTo for bool {
15 fn write_to<T: Write>(&self, sink: &mut T) -> Result<()> {
16 let byte: u8 = match self {
17 false => 0xc2,
18 true => 0xc3,
19 };
20 sink.write_u8(byte)
21 }
22}
23
24impl WriteTo for Int {
25 fn write_to<T: Write>(&self, sink: &mut T) -> Result<()> {
26 match self {
27 Int::U8(i) => {
28 if *i >= 0b10000000 {
29 sink.write_u8(0xcc)?;
30 }
31 sink.write_u8(*i)
32 }
33 Int::U16(i) => {
34 sink.write_u8(0xcd)?;
35 sink.write_u16::<BigEndian>(*i)
36 }
37 Int::U32(i) => {
38 sink.write_u8(0xce)?;
39 sink.write_u32::<BigEndian>(*i)
40 }
41 Int::U64(i) => {
42 sink.write_u8(0xcf)?;
43 sink.write_u64::<BigEndian>(*i)
44 }
45 Int::I8(i) => {
46 if *i > 0 || *i < -0b00100000 {
47 sink.write_u8(0xd0)?;
48 sink.write_i8(*i)
49 } else {
50 let i: u8 = -*i as u8;
51 sink.write_u8(0b11100000 | i)
52 }
53 }
54 Int::I16(i) => {
55 sink.write_u8(0xd1)?;
56 sink.write_i16::<BigEndian>(*i)
57 }
58 Int::I32(i) => {
59 sink.write_u8(0xd2)?;
60 sink.write_i32::<BigEndian>(*i)
61 }
62 Int::I64(i) => {
63 sink.write_u8(0xd3)?;
64 sink.write_i64::<BigEndian>(*i)
65 }
66 }
67 }
68}
69
70impl WriteTo for Float {
71 fn write_to<T: Write>(&self, sink: &mut T) -> Result<()> {
72 match self {
73 Float::F32(f) => {
74 sink.write_u8(0xca)?;
75 sink.write_f32::<BigEndian>(*f)?;
76 }
77 Float::F64(f) => {
78 sink.write_u8(0xcb)?;
79 sink.write_f64::<BigEndian>(*f)?;
80 }
81 }
82 Ok(())
83 }
84}
85
86impl WriteTo for Ext {
87 fn write_to<T: Write>(&self, sink: &mut T) -> Result<()> {
88 let len = self.data.len();
89 match len {
90 1 => sink.write_u8(0xd4)?,
91 2 => sink.write_u8(0xd5)?,
92 4 => sink.write_u8(0xd6)?,
93 8 => sink.write_u8(0xd7)?,
94 16 => sink.write_u8(0xd8)?,
95 i if i <= u8::MAX as usize => {
96 sink.write_u8(0xc7)?;
97 sink.write_u8(i.try_into().unwrap())?;
98 }
99 i if i <= u16::MAX as usize => {
100 sink.write_u8(0xc8)?;
101 sink.write_u16::<BigEndian>(i.try_into().unwrap())?;
102 }
103 i if i <= u32::MAX as usize => {
104 sink.write_u8(0xc9)?;
105 sink.write_u32::<BigEndian>(i.try_into().unwrap())?;
106 }
107 _ => panic!(),
108 }
109 sink.write_u8(self.r#type)?;
110 sink.write_all(self.data.as_slice())
111 }
112}
113
114impl ReadFrom for Value {
115 fn read_from<T: Read>(source: &mut T) -> Result<Self> {
116 let leading = source.read_u8()?;
117 Ok(match leading {
118 0xc0 => Value::Nil,
120 0xc2 => Value::Bool(false),
122 0xc3 => Value::Bool(true),
123 i if i < 0b10000000 => Value::Int(Int::U8(i)),
126 i if i >= 0b11100000 => Value::Int(Int::I8(-((i - 0b11100000) as i8))),
128 0xcc => Value::Int(Int::U8(source.read_u8()?)),
130 0xcd => Value::Int(Int::U16(source.read_u16::<BigEndian>()?)),
131 0xce => Value::Int(Int::U32(source.read_u32::<BigEndian>()?)),
132 0xcf => Value::Int(Int::U64(source.read_u64::<BigEndian>()?)),
133 0xd0 => Value::Int(Int::I8(source.read_i8()?)),
135 0xd1 => Value::Int(Int::I16(source.read_i16::<BigEndian>()?)),
136 0xd2 => Value::Int(Int::I32(source.read_i32::<BigEndian>()?)),
137 0xd3 => Value::Int(Int::I64(source.read_i64::<BigEndian>()?)),
138 0xca => Value::Float(Float::F32(source.read_f32::<BigEndian>()?)),
140 0xcb => Value::Float(Float::F64(source.read_f64::<BigEndian>()?)),
141 i if i & 0b11100000 == 0b10100000 => {
143 let len: usize = (i & 0b00011111).into();
144 let mut bytes: Vec<u8> = vec![0u8; len];
145 source.read_exact(&mut bytes)?;
146 Value::Str(String::from_utf8(bytes).unwrap())
147 }
148 i @ (0xd9..=0xdb) => {
149 let len: usize = match i {
150 0xd9 => source.read_u8()?.into(),
151 0xda => source.read_u16::<BigEndian>()?.into(),
152 0xdb => source.read_u32::<BigEndian>()?.try_into().unwrap(),
153 _ => panic!(),
154 };
155 let mut bytes: Vec<u8> = vec![0u8; len];
156 source.read_exact(&mut bytes)?;
157 Value::Str(String::from_utf8(bytes).unwrap())
158 }
159 i @ (0xc4..=0xc6) => {
161 let len: usize = match i {
162 0xc4 => source.read_u8()?.into(),
163 0xc5 => source.read_u16::<BigEndian>()?.into(),
164 0xc6 => source.read_u32::<BigEndian>()?.try_into().unwrap(),
165 _ => panic!(),
166 };
167 let mut bytes: Vec<u8> = vec![0u8; len];
168 source.read_exact(&mut bytes)?;
169 Value::Bin(bytes)
170 }
171 i if i & 0b11110000 == 0b10010000 => {
173 let len: usize = (i & 0b00001111).into();
174 let mut arr: Vec<Value> = vec![];
175 for _ in 0..len {
176 arr.push(Value::read_from(&mut *source)?);
177 }
178 Value::Arr(arr)
179 }
180 i @ (0xdc | 0xdd) => {
181 let len: usize = match i {
182 0xdc => source.read_u16::<BigEndian>()?.into(),
183 0xdd => source.read_u32::<BigEndian>()?.try_into().unwrap(),
184 _ => panic!(),
185 };
186
187 let mut arr: Vec<Value> = vec![];
188 for _ in 0..len {
189 arr.push(Value::read_from(&mut *source)?);
190 }
191 Value::Arr(arr)
192 }
193 i if (i & 0b11110000) == 0b10000000 => {
195 let len: usize = (i & 0b00001111).into();
196 let mut map = vec![];
197 for _ in 0..len {
198 let key: Value = Value::read_from(&mut *source)?;
199 let value: Value = Value::read_from(&mut *source)?;
200 map.push((key, value));
201 }
202 Value::Map(map)
203 }
204 i @ (0xde | 0xdf) => {
205 let len: usize = match i {
206 0xde => source.read_u16::<BigEndian>()?.into(),
207 0xdf => source.read_u32::<BigEndian>()?.try_into().unwrap(),
208 _ => panic!(),
209 };
210 let mut map = vec![];
211 for _ in 0..len {
212 let key: Value = Value::read_from(&mut *source)?;
213 let value: Value = Value::read_from(&mut *source)?;
214 map.push((key, value));
215 }
216 Value::Map(map)
217 }
218 i @ (0xd4 | 0xd5 | 0xd6 | 0xd7 | 0xd8 | 0xc7 | 0xc8 | 0xc9) => {
220 let len: usize = match i {
221 0xd4 => 1,
222 0xd5 => 2,
223 0xd6 => 4,
224 0xd7 => 8,
225 0xd8 => 16,
226 0xc7 => source.read_u8()?.into(),
227 0xc8 => source.read_u16::<BigEndian>()?.into(),
228 0xc9 => source.read_u32::<BigEndian>()?.try_into().unwrap(),
229 _ => panic!(),
230 };
231 let r#type = source.read_u8()?;
232 let mut data = vec![0u8; len];
233 source.read_exact(&mut data)?;
234 Value::Ext(Ext { r#type, data })
235 }
236 i => {
237 panic!("Whaaaa?: {i:x?}");
238 }
239 })
240 }
241}
242
243impl WriteTo for Value {
244 fn write_to<T: Write>(&self, sink: &mut T) -> Result<()> {
245 match self {
246 Value::Nil => sink.write_u8(0xc0),
247 Value::Bool(b) => b.write_to(sink),
248 Value::Int(i) => i.write_to(sink),
249 Value::Float(f) => f.write_to(sink),
250 Value::Str(bytes) => {
251 let len = bytes.len();
252 if len < 0b100000 {
253 let len: u8 = len.try_into().unwrap();
254 sink.write_u8(0b10100000 | len)?;
255 } else if let Ok(len) = TryInto::<u8>::try_into(len) {
256 sink.write_u8(0xd9)?;
257 sink.write_u8(len)?;
258 } else if let Ok(len) = TryInto::<u16>::try_into(len) {
259 sink.write_u8(0xda)?;
260 sink.write_u16::<BigEndian>(len)?;
261 } else if let Ok(len) = TryInto::<u32>::try_into(len) {
262 sink.write_u8(0xdb)?;
263 sink.write_u32::<BigEndian>(len)?;
264 } else {
265 panic!()
266 }
267 sink.write_all(bytes.as_bytes())
268 }
269 Value::Bin(bytes) => {
270 let len = bytes.len();
271 if let Ok(len) = TryInto::<u8>::try_into(len) {
272 sink.write_u8(0xc4)?;
273 sink.write_u8(len)?;
274 } else if let Ok(len) = TryInto::<u16>::try_into(len) {
275 sink.write_u8(0xc5)?;
276 sink.write_u16::<BigEndian>(len)?;
277 } else if let Ok(len) = TryInto::<u32>::try_into(len) {
278 sink.write_u8(0xc6)?;
279 sink.write_u32::<BigEndian>(len)?;
280 }
281 sink.write_all(bytes)
282 }
283 Value::Arr(arr) => {
284 let len = arr.len();
285 if len < 0b10000 {
286 let len: u8 = len.try_into().unwrap();
287 sink.write_u8(0b10010000 | len)?;
288 } else if let Ok(len) = TryInto::<u16>::try_into(len) {
289 sink.write_u8(0xdc)?;
290 sink.write_u16::<BigEndian>(len)?;
291 } else if let Ok(len) = TryInto::<u32>::try_into(len) {
292 sink.write_u8(0xdd)?;
293 sink.write_u32::<BigEndian>(len)?;
294 } else {
295 panic!();
296 }
297 for v in arr {
298 v.write_to(&mut *sink)?;
299 }
300 Ok(())
301 }
302 Value::Map(map) => {
303 let len = map.len();
304 if len < 0b10000 {
305 let len: u8 = len.try_into().unwrap();
306 sink.write_u8(0b10000000 | len)?;
307 } else if let Ok(len) = TryInto::<u16>::try_into(len) {
308 sink.write_u8(0xde)?;
309 sink.write_u16::<BigEndian>(len)?;
310 } else if let Ok(len) = TryInto::<u32>::try_into(len) {
311 sink.write_u8(0xdf)?;
312 sink.write_u32::<BigEndian>(len)?;
313 } else {
314 panic!();
315 }
316 for (k, v) in map {
317 k.write_to(&mut *sink)?;
318 v.write_to(&mut *sink)?;
319 }
320 Ok(())
321 }
322 Value::Ext(e) => e.write_to(sink),
323 }
324 }
325}
326
327#[cfg(test)]
328mod tests {
329 use super::*;
330 fn assert_read_write(value: Value, bytes: &[u8]) {
331 let mut candidate_bytes: Vec<u8> = vec![];
333 value.write_to(&mut candidate_bytes).unwrap();
334 assert_eq!(bytes, candidate_bytes);
335 let mut cursor = bytes;
337 let candidate_value = Value::read_from(&mut cursor).unwrap();
338 assert_eq!(value, candidate_value)
339 }
340
341 #[test]
342 fn nil_read_write() {
343 assert_read_write(Value::Nil, &[0xc0]);
344 }
345
346 #[test]
347 fn bool_read_write() {
348 assert_read_write(Value::Bool(false), &[0xc2]);
349 assert_read_write(Value::Bool(true), &[0xc3]);
350 }
351
352 #[test]
353 fn int_read_write() {
354 assert_read_write(Value::Int(Int::U8(0)), &[0]);
356 assert_read_write(Value::Int(Int::U8(5)), &[5]);
357 assert_read_write(Value::Int(Int::U8(230)), &[0xcc, 230]);
359 assert_read_write(Value::Int(Int::U16(256)), &[0xcd, 1, 0]);
361 assert_read_write(Value::Int(Int::U32(65_536)), &[0xce, 0, 1, 0, 0]);
363 assert_read_write(
365 Value::Int(Int::U64(4_294_967_296)),
366 &[0xcf, 0, 0, 0, 1, 0, 0, 0, 0],
367 );
368 assert_read_write(Value::Int(Int::I8(-6)), &[0b11100000 + 6]);
370 assert_read_write(Value::Int(Int::I8(-100)), &[0xd0, u8::MAX - 100 + 1]);
372 assert_read_write(
374 Value::Int(Int::I16(-100)),
375 &[0xd1, u8::MAX, u8::MAX - 100 + 1],
376 );
377 assert_read_write(
379 Value::Int(Int::I32(-100)),
380 &[0xd2, u8::MAX, u8::MAX, u8::MAX, u8::MAX - 100 + 1],
381 );
382 assert_read_write(
384 Value::Int(Int::I64(-100)),
385 &[
386 0xd3,
387 u8::MAX,
388 u8::MAX,
389 u8::MAX,
390 u8::MAX,
391 u8::MAX,
392 u8::MAX,
393 u8::MAX,
394 u8::MAX - 100 + 1,
395 ],
396 );
397 }
398
399 #[test]
400 fn float_read_write() {
401 assert_read_write(
403 Value::Float(Float::F32(0.3)),
404 &[0xca, 0x3e, 0x99, 0x99, 0x9a],
405 );
406 assert_read_write(
408 Value::Float(Float::F64(0.3)),
409 &[0xcb, 0x3f, 0xd3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33],
410 );
411 }
412
413 #[test]
414 fn str_bin_read_write() {
415 let bytes: Vec<u8> = b"Oh hello there, isn't this an interesting test".into();
416 let len: u8 = bytes.len().try_into().unwrap();
417 assert_read_write(
418 Value::Str(String::from_utf8(bytes.clone()).unwrap()),
419 &[[0xd9, len].as_slice(), bytes.as_slice()].concat(),
420 );
421 assert_read_write(
422 Value::Bin(bytes.clone()),
423 &[[0xc4, len].as_slice(), bytes.as_slice()].concat(),
424 );
425 }
426
427 #[test]
428 fn arr_read_write() {
429 assert_read_write(
430 Value::Arr(vec![Value::Int(Int::U8(1)), Value::Int(Int::U8(2))]),
431 &[0b10010000 | 2, 1, 2],
432 );
433 }
434
435 #[test]
436 fn map_read_write() {
437 assert_read_write(
438 Value::Map(vec![
439 (Value::Int(Int::U8(1)), Value::Int(Int::U8(10))),
440 (Value::Int(Int::U8(2)), Value::Int(Int::U8(20))),
441 ]),
442 &[0b10000000 | 2, 1, 10, 2, 20],
443 );
444 assert_read_write(Value::Map(vec![]), &[128]);
445 }
446
447 #[test]
448 fn ext_read_write() {
449 assert_read_write(
450 Value::Ext(Ext {
451 r#type: 0xa8,
452 data: b"Hi there".into(),
453 }),
454 &[[0xd7, 0xa8].as_slice(), b"Hi there".as_slice()].concat(),
455 );
456 }
457
458 #[test]
459 fn compound_read_write() {
460 assert_read_write(
461 Value::Arr(
462 [
463 Value::Int(Int::U8(0)),
464 Value::Int(Int::U32(0xf264e4f)),
465 Value::Str("nvim_subscribe".into()),
466 Value::Arr([Value::Str("rsnote_open_window".into())].into()),
467 ]
468 .into(),
469 ),
470 &[
471 148, 0, 206, 15, 38, 78, 79, 174, 110, 118, 105, 109, 95, 115, 117, 98, 115, 99,
472 114, 105, 98, 101, 145, 178, 114, 115, 110, 111, 116, 101, 95, 111, 112, 101, 110,
473 95, 119, 105, 110, 100, 111, 119,
474 ],
475 );
476 assert_read_write(
477 Value::Arr(
478 [
479 Value::Int(Int::I8(0)),
480 Value::Int(Int::U32(0x3f0c4a25)),
481 Value::Str("nvim_buf_set_keymap".into()),
482 Value::Arr(
483 [
484 Value::Ext(Ext {
485 r#type: 0,
486 data: [0xcd, 1, 0x2f].into(),
487 }),
488 Value::Str("n".into()),
489 Value::Str("<ESC>".into()),
490 Value::Str("<Cmd>w! .tasks<CR><Cmd>q<CR>".into()),
491 Value::Map([].into()),
492 ]
493 .into(),
494 ),
495 ]
496 .into(),
497 ),
498 &[
499 148, 224, 206, 63, 12, 74, 37, 179, 110, 118, 105, 109, 95, 98, 117, 102, 95, 115,
500 101, 116, 95, 107, 101, 121, 109, 97, 112, 149, 199, 3, 0, 205, 1, 47, 161, 110,
501 165, 60, 69, 83, 67, 62, 188, 60, 67, 109, 100, 62, 119, 33, 32, 46, 116, 97, 115,
502 107, 115, 60, 67, 82, 62, 60, 67, 109, 100, 62, 113, 60, 67, 82, 62, 128,
503 ],
504 );
505 assert_read_write(
506 Value::Arr(
507 [
508 Value::Int(Int::U8(0)),
509 Value::Int(Int::U32(0xc032e486)),
510 Value::Str("nvim_exec_lua".into()),
511 Value::Arr(
512 [
513 Value::Str("return vim.o.columns".into()),
514 Value::Arr([].into()),
515 ]
516 .into(),
517 ),
518 ]
519 .into(),
520 ),
521 &[
522 148, 0, 206, 192, 50, 228, 134, 173, 110, 118, 105, 109, 95, 101, 120, 101, 99, 95,
523 108, 117, 97, 146, 180, 114, 101, 116, 117, 114, 110, 32, 118, 105, 109, 46, 111,
524 46, 99, 111, 108, 117, 109, 110, 115, 144,
525 ],
526 );
527 assert_read_write(
528 Value::Arr(
529 [
530 Value::Int(Int::U8(0)),
531 Value::Int(Int::U32(0x49d10de0)),
532 Value::Str("nvim_buf_set_lines".into()),
533 Value::Arr(
534 [
535 Value::Ext(Ext {
536 r#type: 0,
537 data: [25].into(),
538 }),
539 Value::Int(Int::U8(0)),
540 Value::Int(Int::U8(1)),
541 Value::Bool(false),
542 Value::Arr(
543 [
544 Value::Str("Add the messagepack-rs module".into()),
545 Value::Str(
546 "Delete the
547 local code"
548 .into(),
549 ),
550 Value::Str("Refactor to use the messagepack library".into()),
551 Value::Str("".into()),
552 ]
553 .into(),
554 ),
555 ]
556 .into(),
557 ),
558 ]
559 .into(),
560 ),
561 &[
562 148, 0, 206, 73, 209, 13, 224, 178, 110, 118, 105, 109, 95, 98, 117, 102, 95, 115,
563 101, 116, 95, 108, 105, 110, 101, 115, 149, 212, 0, 25, 0, 1, 194, 148, 189, 65,
564 100, 100, 32, 116, 104, 101, 32, 109, 101, 115, 115, 97, 103, 101, 112, 97, 99,
565 107, 45, 114, 115, 32, 109, 111, 100, 117, 108, 101, 182, 68, 101, 108, 101, 116,
566 101, 32, 116, 104, 101, 10, 32, 108, 111, 99, 97, 108, 32, 99, 111, 100, 101, 217,
567 39, 82, 101, 102, 97, 99, 116, 111, 114, 32, 116, 111, 32, 117, 115, 101, 32, 116,
568 104, 101, 32, 109, 101, 115, 115, 97, 103, 101, 112, 97, 99, 107, 32, 108, 105, 98,
569 114, 97, 114, 121, 160,
570 ],
571 );
572 }
573}