1use crate::consts::*;
2use crate::RawTerm;
3use num_bigint::{BigInt, Sign};
4
5#[cfg(feature = "zlib")]
6use flate2::read::ZlibEncoder;
7#[cfg(feature = "zlib")]
8use flate2::Compression;
9#[cfg(feature = "zlib")]
10use std::io::prelude::*;
11
12pub fn to_bytes(raw: RawTerm) -> Vec<u8> {
13 internal_to_binary(raw, true)
14}
15
16#[cfg(feature = "zlib")]
17pub fn to_gzip_bytes(raw: RawTerm, level: Compression) -> std::io::Result<Vec<u8>> {
18 let bytes = internal_to_binary(raw, false);
19 let mut buffer = Vec::with_capacity(bytes.len());
20 let mut encoder = ZlibEncoder::new(&bytes[..], level);
21 push_prefix(&mut buffer);
22 buffer.push(ZLIB);
23 let length = bytes.len() as u32;
24 buffer.extend_from_slice(&length.to_be_bytes());
25 encoder.read_to_end(&mut buffer)?;
26 Ok(buffer)
27}
28
29pub fn internal_to_binary(raw: RawTerm, add_prefix: bool) -> Vec<u8> {
30 use RawTerm::*;
31 match raw {
32 Atom(x) => atom(x, add_prefix),
33 SmallAtom(x) => small_atom(x, add_prefix),
34 AtomDeprecated(x) => atom_deprecated(x, add_prefix),
35 SmallAtomDeprecated(x) => small_atom_deprecated(x, add_prefix),
36 Float(x) => float(*x, add_prefix),
37 Nil => nil(add_prefix),
38 SmallInt(x) => small_int(x, add_prefix),
39 Int(x) => int(x, add_prefix),
40 String(x) => string(x, add_prefix),
41 Binary(x) => binary(x, add_prefix),
42 BitBinary { binary, bit, bits } => bitbinary(binary, bit, bits, add_prefix),
43 SmallBigInt(x) => small_big_int(x, add_prefix),
44 LargeBigInt(x) => large_big_int(x, add_prefix),
45 SmallTuple(x) => small_tuple(x, add_prefix),
46 LargeTuple(x) => large_tuple(x, add_prefix),
47 List(x) => list(x, add_prefix),
48 Map(x) => map(x, add_prefix),
49 Port { node, id, creation } => port(*node, id, creation, add_prefix),
50 NewPort { node, id, creation } => new_port(*node, id, creation, add_prefix),
51 Ref { node, id, creation } => reference(*node, id, creation, add_prefix),
52 NewerRef { node, id, creation } => newer_reference(*node, id, creation, add_prefix),
53 Pid {
54 node,
55 id,
56 serial,
57 creation,
58 } => pid(*node, id, serial, creation, add_prefix),
59 NewPid {
60 node,
61 id,
62 serial,
63 creation,
64 } => new_pid(*node, id, serial, creation, add_prefix),
65 Function {
66 size,
67 arity,
68 uniq,
69 index,
70 module,
71 old_index,
72 old_uniq,
73 pid,
74 free_var,
75 } => function(
76 size, arity, uniq, index, *module, *old_index, *old_uniq, *pid, free_var, add_prefix,
77 ),
78 Improper(_) => unreachable!(),
79 }
80}
81
82fn insert_prefix(bytes: &mut Vec<u8>) {
83 bytes.insert(0, REVISION);
84}
85
86fn push_prefix(bytes: &mut Vec<u8>) {
87 bytes.push(REVISION);
88}
89
90fn small_atom(raw: String, add_prefix: bool) -> Vec<u8> {
91 let mut bytes = raw.into_bytes();
92 let length = bytes.len() as u8;
93 bytes.insert(0, length);
94 bytes.insert(0, SMALL_ATOM_UTF8_EXT);
95 if add_prefix {
96 insert_prefix(&mut bytes)
97 };
98 bytes
99}
100
101fn atom(raw: String, add_prefix: bool) -> Vec<u8> {
102 let bytes = raw.into_bytes();
103 let length = bytes.len();
104 let mut buffer = Vec::with_capacity(length + 4);
105
106 if add_prefix {
107 push_prefix(&mut buffer)
108 };
109 buffer.push(ATOM_UTF8_EXT);
110 buffer.extend((length as u16).to_be_bytes());
111 buffer.extend(bytes);
112 buffer
113}
114
115fn small_atom_deprecated(raw: String, add_prefix: bool) -> Vec<u8> {
116 let mut bytes = raw.into_bytes();
117 let length = bytes.len() as u8;
118 bytes.insert(0, length);
119 bytes.insert(0, SMALL_ATOM_EXT_DEPRECATED);
120 if add_prefix {
121 insert_prefix(&mut bytes)
122 };
123 bytes
124}
125
126fn atom_deprecated(raw: String, add_prefix: bool) -> Vec<u8> {
127 let bytes = raw.into_bytes();
128 let length = bytes.len();
129 let mut buffer = Vec::with_capacity(length + 4);
130
131 if add_prefix {
132 push_prefix(&mut buffer)
133 };
134 buffer.push(ATOM_EXT_DEPRECATED);
135 buffer.extend((length as u16).to_be_bytes());
136 buffer.extend(bytes);
137 buffer
138}
139
140fn float(raw: f64, add_prefix: bool) -> Vec<u8> {
141 let mut buffer = Vec::with_capacity(10);
142
143 if add_prefix {
144 push_prefix(&mut buffer)
145 };
146 buffer.push(NEW_FLOAT_EXT);
147 buffer.extend(raw.to_be_bytes());
148 buffer
149}
150
151fn nil(add_prefix: bool) -> Vec<u8> {
152 if add_prefix {
153 vec![REVISION, NIL_EXT]
154 } else {
155 vec![NIL_EXT]
156 }
157}
158
159fn small_int(raw: u8, add_prefix: bool) -> Vec<u8> {
160 if add_prefix {
161 vec![REVISION, SMALL_INTEGER_EXT, raw]
162 } else {
163 vec![SMALL_INTEGER_EXT, raw]
164 }
165}
166
167fn int(raw: i32, add_prefix: bool) -> Vec<u8> {
168 let mut buffer = Vec::with_capacity(6);
169
170 if add_prefix {
171 push_prefix(&mut buffer)
172 };
173 buffer.push(INTEGER_EXT);
174 buffer.extend(raw.to_be_bytes());
175 buffer
176}
177
178fn string(mut raw: Vec<u8>, add_prefix: bool) -> Vec<u8> {
179 let length = raw.len();
180 let mut buffer = Vec::with_capacity(length + 4);
181
182 if add_prefix {
183 push_prefix(&mut buffer)
184 };
185 buffer.push(STRING_EXT);
186 buffer.extend((length as u16).to_be_bytes());
187 buffer.append(&mut raw);
188 buffer
189}
190
191fn binary(mut raw: Vec<u8>, add_prefix: bool) -> Vec<u8> {
192 let length = raw.len();
193 let mut buffer = Vec::with_capacity(length + 6);
194
195 if add_prefix {
196 push_prefix(&mut buffer)
197 };
198 buffer.push(BINARY_EXT);
199 buffer.extend((length as u32).to_be_bytes());
200 buffer.append(&mut raw);
201 buffer
202}
203
204fn bitbinary(mut binary: Vec<u8>, bit: u8, bits: u8, add_prefix: bool) -> Vec<u8> {
205 let length = binary.len();
206 let mut buffer = Vec::with_capacity(length + 7);
207
208 if add_prefix {
209 push_prefix(&mut buffer)
210 };
211 buffer.push(BIT_BINARY_EXT);
212 buffer.extend(((length as u32) + 1).to_be_bytes());
213 buffer.push(bits);
214 buffer.append(&mut binary);
215 buffer.push(bit << (8u8.saturating_sub(bits)));
217 buffer
218}
219
220fn small_big_int(raw: BigInt, add_prefix: bool) -> Vec<u8> {
221 let (sign, mut bytes) = raw.to_bytes_le();
222 let sign = sign_to_byte(sign);
223
224 let mut buffer = Vec::with_capacity(bytes.len() + 4);
225
226 if add_prefix {
227 push_prefix(&mut buffer)
228 };
229 buffer.push(SMALL_BIG_EXT);
230 buffer.push(bytes.len() as u8);
231 buffer.push(sign);
232 buffer.append(&mut bytes);
233 buffer
234}
235
236fn large_big_int(raw: BigInt, add_prefix: bool) -> Vec<u8> {
237 let (sign, mut bytes) = raw.to_bytes_le();
238 let sign = sign_to_byte(sign);
239 let length = bytes.len();
240
241 let mut buffer = Vec::with_capacity(length + 7);
242
243 if add_prefix {
244 push_prefix(&mut buffer)
245 };
246 buffer.push(LARGE_BIG_EXT);
247 buffer.extend((length as u32).to_be_bytes());
248 buffer.push(sign);
249 buffer.append(&mut bytes);
250 buffer
251}
252
253fn small_tuple(raw: Vec<RawTerm>, add_prefix: bool) -> Vec<u8> {
254 let arity = raw.len();
255 let mut bytes: Vec<u8> = raw
256 .into_iter()
257 .flat_map(|x| internal_to_binary(x, false))
258 .collect();
259
260 let mut buffer = Vec::with_capacity(bytes.len() + 3);
261
262 if add_prefix {
263 push_prefix(&mut buffer)
264 };
265 buffer.push(SMALL_TUPLE_EXT);
266 buffer.push(arity as u8);
267 buffer.append(&mut bytes);
268 buffer
269}
270
271fn large_tuple(raw: Vec<RawTerm>, add_prefix: bool) -> Vec<u8> {
272 let arity = raw.len();
273 let mut bytes: Vec<u8> = raw
274 .into_iter()
275 .flat_map(|x| internal_to_binary(x, false))
276 .collect();
277
278 let mut buffer = Vec::with_capacity(bytes.len() + 6);
279
280 if add_prefix {
281 push_prefix(&mut buffer)
282 };
283 buffer.push(LARGE_TUPLE_EXT);
284 buffer.extend((arity as u32).to_be_bytes());
285 buffer.append(&mut bytes);
286 buffer
287}
288
289fn list(mut raw: Vec<RawTerm>, add_prefix: bool) -> Vec<u8> {
290 let tail = raw.pop();
291 let tail = if let Some(RawTerm::Improper(x)) = tail {
292 vec![*x]
293 } else if let Some(x) = tail {
294 vec![x, RawTerm::Nil]
295 } else {
296 vec![RawTerm::Nil]
297 };
298
299 raw.extend(tail);
300 let arity = raw.len() - 1;
301 let mut bytes: Vec<u8> = raw
302 .into_iter()
303 .flat_map(|x| internal_to_binary(x, false))
304 .collect();
305
306 let mut buffer = Vec::with_capacity(bytes.len() + 6);
307 if add_prefix {
308 push_prefix(&mut buffer)
309 };
310 buffer.push(LIST_EXT);
311 buffer.extend((arity as u32).to_be_bytes());
312 buffer.append(&mut bytes);
313 buffer
314}
315
316fn map(raw: Vec<(RawTerm, RawTerm)>, add_prefix: bool) -> Vec<u8> {
317 let arity = raw.len();
318 let mut bytes: Vec<u8> = raw
319 .into_iter()
320 .flat_map(|(a, b)| {
321 internal_to_binary(a, false)
322 .into_iter()
323 .chain(internal_to_binary(b, false))
324 })
325 .collect();
326
327 let mut buffer = Vec::with_capacity(bytes.len() + 6);
328
329 if add_prefix {
330 push_prefix(&mut buffer)
331 };
332 buffer.push(MAP_EXT);
333 buffer.extend((arity as u32).to_be_bytes());
334 buffer.append(&mut bytes);
335 buffer
336}
337
338fn port(node: RawTerm, id: u32, creation: u8, add_prefix: bool) -> Vec<u8> {
339 let node_binary = internal_to_binary(node, false);
340
341 let mut buffer = Vec::with_capacity(node_binary.len() + 7);
342
343 if add_prefix {
344 push_prefix(&mut buffer)
345 };
346 buffer.push(PORT_EXT);
347 buffer.extend(node_binary);
348 buffer.extend(id.to_be_bytes());
349 buffer.push(creation);
350 buffer
351}
352
353fn new_port(node: RawTerm, id: u32, creation: u32, add_prefix: bool) -> Vec<u8> {
354 let node_binary = internal_to_binary(node, false);
355
356 let mut buffer = Vec::with_capacity(node_binary.len() + 7);
357
358 if add_prefix {
359 push_prefix(&mut buffer)
360 };
361 buffer.push(NEW_PORT_EXT);
362 buffer.extend(node_binary);
363 buffer.extend(id.to_be_bytes());
364 buffer.extend(creation.to_be_bytes());
365 buffer
366}
367
368fn reference(node: RawTerm, id: Vec<u32>, creation: u8, add_prefix: bool) -> Vec<u8> {
369 let id_length = id.len();
370 let node_binary = internal_to_binary(node, false);
371 let mut id_bytes: Vec<u8> = Vec::new();
372 for part in id {
373 id_bytes.extend(part.to_be_bytes());
374 }
375
376 let mut buffer = Vec::with_capacity(node_binary.len() + id_bytes.len() + 5);
377
378 if add_prefix {
379 push_prefix(&mut buffer)
380 };
381 buffer.push(NEW_REFERENCE_EXT);
382 buffer.extend((id_length as u16).to_be_bytes());
383 buffer.extend(node_binary);
384 buffer.extend(creation.to_be_bytes());
385 buffer.extend(id_bytes);
386 buffer
387}
388
389fn newer_reference(node: RawTerm, id: Vec<u32>, creation: u32, add_prefix: bool) -> Vec<u8> {
390 let id_length = id.len();
391 let node_binary = internal_to_binary(node, false);
392 let mut id_bytes: Vec<u8> = Vec::new();
393 for part in id {
394 id_bytes.extend(part.to_be_bytes());
395 }
396
397 let mut buffer = Vec::with_capacity(node_binary.len() + id_bytes.len() + 5);
398
399 if add_prefix {
400 push_prefix(&mut buffer)
401 };
402 buffer.push(NEWER_REFERENCE_EXT);
403 buffer.extend((id_length as u16).to_be_bytes());
404 buffer.extend(node_binary);
405 buffer.extend(creation.to_be_bytes());
406 buffer.extend(id_bytes);
407 buffer
408}
409
410fn pid(node: RawTerm, id: u32, serial: u32, creation: u8, add_prefix: bool) -> Vec<u8> {
411 let node_binary = internal_to_binary(node, false);
412
413 let mut buffer = Vec::with_capacity(node_binary.len() + 11);
414
415 if add_prefix {
416 push_prefix(&mut buffer)
417 };
418 buffer.push(PID_EXT);
419 buffer.extend(node_binary);
420 buffer.extend(id.to_be_bytes());
421 buffer.extend(serial.to_be_bytes());
422 buffer.push(creation);
423 buffer
424}
425fn new_pid(node: RawTerm, id: u32, serial: u32, creation: u32, add_prefix: bool) -> Vec<u8> {
426 let node_binary = internal_to_binary(node, false);
427
428 let mut buffer = Vec::with_capacity(node_binary.len() + 11);
429
430 if add_prefix {
431 push_prefix(&mut buffer)
432 };
433 buffer.push(NEW_PID_EXT);
434 buffer.extend(node_binary);
435 buffer.extend(id.to_be_bytes());
436 buffer.extend(serial.to_be_bytes());
437 buffer.extend(creation.to_be_bytes());
438 buffer
439}
440fn function(
441 size: u32,
442 arity: u8,
443 uniq: [u8; 16],
444 index: u32,
445 module: RawTerm,
446 old_index: RawTerm,
447 old_uniq: RawTerm,
448 pid: RawTerm,
449 free_var: Vec<RawTerm>,
450 add_prefix: bool,
451) -> Vec<u8> {
452 let free_var_length = free_var.len();
453 let module_binary = internal_to_binary(module, false);
454 let pid_binary = internal_to_binary(pid, false);
455 let old_index = internal_to_binary(old_index, false);
456 let old_uniq = internal_to_binary(old_uniq, false);
457 let free_var_bytes: Vec<u8> = free_var
458 .into_iter()
459 .flat_map(|x| internal_to_binary(x, false))
460 .collect();
461
462 let mut buffer =
463 Vec::with_capacity(module_binary.len() + pid_binary.len() + free_var_bytes.len() + 31);
464 if add_prefix {
465 push_prefix(&mut buffer)
466 };
467 buffer.push(NEW_FUN_EXT);
468 buffer.extend(size.to_be_bytes());
469 buffer.push(arity);
470 buffer.extend(uniq);
471 buffer.extend(index.to_be_bytes());
472 buffer.extend((free_var_length as u32).to_be_bytes());
473 buffer.extend(module_binary);
474 buffer.extend(old_index);
475 buffer.extend(old_uniq);
476 buffer.extend(pid_binary);
477 buffer.extend(free_var_bytes);
478 buffer
479}
480
481fn sign_to_byte(sign: Sign) -> u8 {
482 match sign {
483 Sign::Minus => 1,
484 _ => 0,
485 }
486}
487
488#[cfg(test)]
489mod binary_tests {
490 use crate::consts::REVISION;
491 use crate::{read_binary, to_bytes, RawTerm};
492 use num_bigint::{BigInt, BigUint};
493
494 #[test]
495 fn small_atom() {
496 let out = to_bytes(RawTerm::SmallAtom("test".to_string()));
497 assert_eq!(out, vec![REVISION, 119, 4, 116, 101, 115, 116])
498 }
499
500 #[test]
501 fn atom() {
502 let out = to_bytes(RawTerm::Atom("test".to_string()));
503 assert_eq!(out, vec![REVISION, 118, 0, 4, 116, 101, 115, 116])
504 }
505
506 #[test]
507 fn small_atom_deprecated() {
508 let out = to_bytes(RawTerm::SmallAtomDeprecated("test".to_string()));
509 assert_eq!(out, vec![REVISION, 115, 4, 116, 101, 115, 116])
510 }
511
512 #[test]
513 fn atom_deprecated() {
514 let out = to_bytes(RawTerm::AtomDeprecated("test".to_string()));
515 assert_eq!(out, vec![REVISION, 100, 0, 4, 116, 101, 115, 116])
516 }
517
518 #[test]
519 fn float() {
520 let out = to_bytes(RawTerm::Float(3.14.into()));
521 assert_eq!(out, vec![REVISION, 70, 64, 9, 30, 184, 81, 235, 133, 31])
522 }
523
524 #[test]
525 fn nil() {
526 let out = to_bytes(RawTerm::Nil);
527 assert_eq!(out, vec![REVISION, 106])
528 }
529
530 #[test]
531 fn small_int() {
532 let out = to_bytes(RawTerm::SmallInt(4));
533 assert_eq!(out, vec![REVISION, 97, 4])
534 }
535
536 #[test]
537 fn int() {
538 let out = to_bytes(RawTerm::Int(-13));
539 assert_eq!(out, vec![REVISION, 98, 255, 255, 255, 243]);
540
541 let out = to_bytes(RawTerm::Int(12345));
542 assert_eq!(out, vec![REVISION, 98, 0, 0, 48, 57])
543 }
544
545 #[test]
546 fn string() {
547 let out = to_bytes(RawTerm::String(b"testing".to_vec()));
548 assert_eq!(
549 out,
550 vec![REVISION, 107, 0, 7, 116, 101, 115, 116, 105, 110, 103]
551 )
552 }
553
554 #[test]
555 fn binary() {
556 let out = to_bytes(RawTerm::Binary(b"testing".to_vec()));
557 assert_eq!(
558 out,
559 vec![REVISION, 109, 0, 0, 0, 7, 116, 101, 115, 116, 105, 110, 103]
560 )
561 }
562
563 #[test]
564 fn bitbinary() {
565 let out = to_bytes(RawTerm::BitBinary {
566 binary: b"testing".to_vec(),
567 bit: 13,
568 bits: 4,
569 });
570 assert_eq!(
571 out,
572 vec![REVISION, 77, 0, 0, 0, 8, 4, 116, 101, 115, 116, 105, 110, 103, 208]
573 );
574
575 let out = to_bytes(RawTerm::BitBinary {
576 binary: vec![95],
577 bit: 23,
578 bits: 5,
579 });
580 assert_eq!(out, vec![REVISION, 77, 0, 0, 0, 2, 5, 95, 184]);
581 }
582
583 #[test]
584 fn small_big_int() {
585 let out = to_bytes(RawTerm::SmallBigInt(
586 BigInt::parse_bytes(b"123456789123456789123456789", 10).unwrap(),
587 ));
588 assert_eq!(
589 out,
590 vec![REVISION, 110, 11, 0, 21, 95, 4, 124, 159, 177, 227, 242, 253, 30, 102]
591 )
592 }
593
594 #[test]
595 fn large_big_int() {
596 use num_traits::pow::Pow;
597
598 let expected = read_binary("bins/large_big_int.bin").unwrap();
599 let nineninenine = BigUint::parse_bytes(b"999", 10).unwrap();
600 let out = to_bytes(RawTerm::LargeBigInt(BigInt::from(
601 nineninenine.clone().pow(&nineninenine),
602 )));
603
604 assert_eq!(expected, out);
605 }
606
607 #[test]
608 fn small_tuple() {
609 let out = to_bytes(RawTerm::SmallTuple(vec![
610 RawTerm::String(b"testing".to_vec()),
611 RawTerm::SmallInt(1),
612 ]));
613
614 assert_eq!(
615 out,
616 vec![REVISION, 104, 2, 107, 0, 7, 116, 101, 115, 116, 105, 110, 103, 97, 1]
617 )
618 }
619
620 #[test]
621 fn large_tuple() {
622 let out = to_bytes(RawTerm::LargeTuple(vec![
623 RawTerm::String(b"testing".to_vec()),
624 RawTerm::SmallInt(1),
625 ]));
626
627 assert_eq!(
628 out,
629 vec![REVISION, 105, 0, 0, 0, 2, 107, 0, 7, 116, 101, 115, 116, 105, 110, 103, 97, 1]
630 )
631 }
632
633 #[test]
634 fn list() {
635 let out = to_bytes(RawTerm::List(vec![RawTerm::String(b"testing".to_vec())]));
636
637 assert_eq!(
638 out,
639 vec![REVISION, 108, 0, 0, 0, 1, 107, 0, 7, 116, 101, 115, 116, 105, 110, 103, 106]
640 )
641 }
642
643 #[test]
644 fn improper_list() {
645 let out = to_bytes(RawTerm::List(vec![
646 RawTerm::String(b"testing".to_vec()),
647 RawTerm::Improper(Box::new(RawTerm::SmallInt(3))),
648 ]));
649
650 assert_eq!(
651 out,
652 vec![REVISION, 108, 0, 0, 0, 1, 107, 0, 7, 116, 101, 115, 116, 105, 110, 103, 97, 3]
653 )
654 }
655
656 #[test]
657 fn atom_map() {
658 let out = to_bytes(RawTerm::Map(
659 vec![
660 (
661 RawTerm::AtomDeprecated("other".to_string()),
662 RawTerm::Binary(b"test".to_vec()),
663 ),
664 (
665 RawTerm::AtomDeprecated("some".to_string()),
666 RawTerm::SmallInt(3),
667 ),
668 ]
669 .into_iter()
670 .collect(),
671 ));
672
673 assert_eq!(
674 out,
675 vec![
676 REVISION, 116, 0, 0, 0, 2, 100, 0, 5, 111, 116, 104, 101, 114, 109, 0, 0, 0, 4,
677 116, 101, 115, 116, 100, 0, 4, 115, 111, 109, 101, 97, 3
678 ]
679 )
680 }
681
682 #[test]
683 fn map() {
684 use RawTerm::*;
685 let map = vec![
686 (SmallInt(1), Binary(b"one".to_vec())),
687 (
688 List(vec![Binary(b"list as a key".to_vec())]),
689 List(vec![
690 Binary(b"another".to_vec()),
691 Map(vec![(
692 AtomDeprecated("test".to_string()),
693 AtomDeprecated("false".to_string()),
694 )]
695 .into_iter()
696 .collect()),
697 ]),
698 ),
699 (Binary(b"float".to_vec()), Float(3.14.into())),
700 (
701 Binary(b"large".to_vec()),
702 SmallBigInt(BigInt::parse_bytes(b"123456789123456789", 10).unwrap()),
703 ),
704 (
705 Binary(b"nested".to_vec()),
706 Map(vec![(Binary(b"ok".to_vec()), Nil)].into_iter().collect()),
707 ),
708 (
709 AtomDeprecated("tuple".to_string()),
710 SmallTuple(vec![SmallInt(1), AtomDeprecated("more".to_string())]),
711 ),
712 ]
713 .into_iter()
714 .collect();
715
716 let out = to_bytes(RawTerm::Map(map));
717
718 assert_eq!(
719 out,
720 vec![
721 REVISION, 116, 0, 0, 0, 6, 97, 1, 109, 0, 0, 0, 3, 111, 110, 101, 108, 0, 0, 0, 1,
722 109, 0, 0, 0, 13, 108, 105, 115, 116, 32, 97, 115, 32, 97, 32, 107, 101, 121, 106,
723 108, 0, 0, 0, 2, 109, 0, 0, 0, 7, 97, 110, 111, 116, 104, 101, 114, 116, 0, 0, 0,
724 1, 100, 0, 4, 116, 101, 115, 116, 100, 0, 5, 102, 97, 108, 115, 101, 106, 109, 0,
725 0, 0, 5, 102, 108, 111, 97, 116, 70, 64, 9, 30, 184, 81, 235, 133, 31, 109, 0, 0,
726 0, 5, 108, 97, 114, 103, 101, 110, 8, 0, 21, 95, 208, 172, 75, 155, 182, 1, 109, 0,
727 0, 0, 6, 110, 101, 115, 116, 101, 100, 116, 0, 0, 0, 1, 109, 0, 0, 0, 2, 111, 107,
728 106, 100, 0, 5, 116, 117, 112, 108, 101, 104, 2, 97, 1, 100, 0, 4, 109, 111, 114,
729 101
730 ]
731 );
732 }
733
734 #[test]
735 fn port() {
736 let out = to_bytes(RawTerm::Port {
737 node: Box::new(RawTerm::SmallAtom("something@something".to_string())),
738 id: 123,
739 creation: 2,
740 });
741
742 assert_eq!(
743 out,
744 vec![
745 REVISION, 102, 119, 19, 115, 111, 109, 101, 116, 104, 105, 110, 103, 64, 115, 111,
746 109, 101, 116, 104, 105, 110, 103, 0, 0, 0, 123, 2
747 ]
748 )
749 }
750
751 #[test]
752 fn new_port() {
753 let out = to_bytes(RawTerm::NewPort {
754 node: Box::new(RawTerm::SmallAtom("something@something".to_string())),
755 id: 123,
756 creation: 2,
757 });
758
759 assert_eq!(
760 out,
761 vec![
762 REVISION, 89, 119, 19, 115, 111, 109, 101, 116, 104, 105, 110, 103, 64, 115, 111,
763 109, 101, 116, 104, 105, 110, 103, 0, 0, 0, 123, 0, 0, 0, 2
764 ]
765 )
766 }
767
768 #[test]
769 fn reference() {
770 let out = to_bytes(RawTerm::Ref {
771 node: Box::new(RawTerm::AtomDeprecated("something@something".to_string())),
772 id: vec![158726, 438566918, 237133],
773 creation: 2,
774 });
775
776 assert_eq!(
777 out,
778 vec![
779 REVISION, 114, 0, 3, 100, 0, 19, 115, 111, 109, 101, 116, 104, 105, 110, 103, 64,
780 115, 111, 109, 101, 116, 104, 105, 110, 103, 2, 0, 2, 108, 6, 26, 36, 0, 6, 0, 3,
781 158, 77
782 ]
783 )
784 }
785
786 #[test]
787 fn newer_reference() {
788 let out = to_bytes(RawTerm::NewerRef {
789 node: Box::new(RawTerm::AtomDeprecated("something@something".to_string())),
790 id: vec![158726, 438566918, 237133],
791 creation: 2,
792 });
793
794 assert_eq!(
795 out,
796 vec![
797 REVISION, 90, 0, 3, 100, 0, 19, 115, 111, 109, 101, 116, 104, 105, 110, 103, 64,
798 115, 111, 109, 101, 116, 104, 105, 110, 103, 0, 0, 0, 2, 0, 2, 108, 6, 26, 36, 0,
799 6, 0, 3, 158, 77
800 ]
801 )
802 }
803
804 #[test]
805 fn pid() {
806 let out = to_bytes(RawTerm::Pid {
807 node: Box::new(RawTerm::SmallAtom("something@something".to_string())),
808 id: 123,
809 serial: 654,
810 creation: 2,
811 });
812
813 assert_eq!(
814 out,
815 vec![
816 REVISION, 103, 119, 19, 115, 111, 109, 101, 116, 104, 105, 110, 103, 64, 115, 111,
817 109, 101, 116, 104, 105, 110, 103, 0, 0, 0, 123, 0, 0, 2, 142, 2
818 ]
819 )
820 }
821
822 #[test]
823 fn function() {
824 let input = RawTerm::Function {
825 size: 134,
826 arity: 0,
827 uniq: [
828 241, 72, 50, 109, 70, 84, 198, 45, 20, 94, 42, 25, 184, 243, 5, 100,
829 ],
830 index: 21,
831 module: Box::new(RawTerm::AtomDeprecated("erl_eval".to_string())),
832 old_index: Box::new(RawTerm::SmallInt(21)),
833 old_uniq: Box::new(RawTerm::Int(126501267)),
834 pid: Box::new(RawTerm::Pid {
835 node: Box::new(RawTerm::AtomDeprecated("nonode@nohost".to_string())),
836 id: 102,
837 serial: 0,
838 creation: 0,
839 }),
840 free_var: vec![RawTerm::SmallTuple(vec![
841 RawTerm::Nil,
842 RawTerm::AtomDeprecated("none".to_string()),
843 RawTerm::AtomDeprecated("none".to_string()),
844 RawTerm::List(vec![RawTerm::SmallTuple(vec![
845 RawTerm::AtomDeprecated("clause".to_string()),
846 RawTerm::SmallInt(3),
847 RawTerm::Nil,
848 RawTerm::Nil,
849 RawTerm::List(vec![RawTerm::SmallTuple(vec![
850 RawTerm::AtomDeprecated("atom".to_string()),
851 RawTerm::SmallInt(0),
852 RawTerm::AtomDeprecated("nil".to_string()),
853 ])]),
854 ])]),
855 ])],
856 };
857 let out = to_bytes(input);
858
859 assert_eq!(
860 out,
861 vec![
862 REVISION, 112, 0, 0, 0, 134, 0, 241, 72, 50, 109, 70, 84, 198, 45, 20, 94, 42, 25,
863 184, 243, 5, 100, 0, 0, 0, 21, 0, 0, 0, 1, 100, 0, 8, 101, 114, 108, 95, 101, 118,
864 97, 108, 97, 21, 98, 7, 138, 65, 147, 103, 100, 0, 13, 110, 111, 110, 111, 100,
865 101, 64, 110, 111, 104, 111, 115, 116, 0, 0, 0, 102, 0, 0, 0, 0, 0, 104, 4, 106,
866 100, 0, 4, 110, 111, 110, 101, 100, 0, 4, 110, 111, 110, 101, 108, 0, 0, 0, 1, 104,
867 5, 100, 0, 6, 99, 108, 97, 117, 115, 101, 97, 3, 106, 106, 108, 0, 0, 0, 1, 104, 3,
868 100, 0, 4, 97, 116, 111, 109, 97, 0, 100, 0, 3, 110, 105, 108, 106, 106
869 ]
870 )
871 }
872
873 #[test]
874 #[cfg(feature = "zlib")]
875 fn gzip_bytes() {
876 use crate::to_gzip_bytes;
877 use flate2::Compression;
878
879 let list = RawTerm::List((0..100).into_iter().map(RawTerm::Int).collect());
880
881 let expected = vec![
887 131, 80, 0, 0, 1, 250, 120, 156, 21, 196, 51, 150, 67, 1, 0, 0, 192, 191, 182, 109,
888 219, 182, 109, 198, 70, 149, 151, 251, 215, 201, 52, 83, 14, 130, 160, 152, 175, 18,
889 160, 6, 181, 168, 67, 61, 26, 208, 136, 38, 52, 163, 5, 173, 104, 67, 59, 58, 208, 137,
890 46, 116, 163, 7, 189, 232, 67, 63, 6, 48, 136, 33, 12, 99, 4, 163, 24, 195, 56, 38, 48,
891 137, 41, 76, 99, 6, 179, 152, 195, 60, 22, 176, 136, 37, 44, 99, 5, 171, 88, 195, 58,
892 54, 176, 137, 45, 108, 99, 7, 187, 216, 195, 62, 14, 112, 136, 35, 28, 227, 4, 167, 56,
893 195, 57, 46, 112, 137, 43, 92, 227, 6, 183, 184, 195, 61, 30, 240, 136, 39, 60, 227, 5,
894 175, 120, 195, 59, 62, 240, 137, 47, 124, 227, 7, 191, 248, 195, 63, 66, 8, 35, 130,
895 40, 98, 136, 35, 129, 36, 82, 72, 35, 131, 44, 114, 200, 163, 80, 170, 0, 4, 44, 58,
896 217,
897 ];
898
899 let output = to_gzip_bytes(list, Compression::new(6)).unwrap();
900
901 assert_eq!(expected, output);
902 }
903}