1use linked_hash_map::LinkedHashMap;
2use serde::de;
3use serde::de::{SeqAccess, Unexpected, Visitor};
4use serde::{Deserialize, Deserializer};
5use std::collections::HashMap;
6use std::fmt;
7use std::io::Read;
8
9pub fn read_protocol<R: Read>(reader: R) -> serde_json::Result<Protocol> {
10 serde_json::from_reader(reader)
11}
12
13#[derive(Debug, Eq, PartialEq, Deserialize)]
14pub struct Protocol {
15 pub types: LinkedHashMap<String, DataType>,
16 #[serde(flatten)]
17 pub namespaces: LinkedHashMap<String, Namespace>,
18}
19
20#[derive(Debug, Eq, PartialEq, Deserialize)]
21#[serde(untagged)]
22pub enum Namespace {
23 Map(LinkedHashMap<String, Namespace>),
24 DataType(DataType),
25}
26
27#[derive(Debug, Eq, PartialEq, Deserialize)]
28#[serde(untagged)]
29pub enum DataType {
30 Conditional(Box<Conditional>),
31 Numeric(Numeric),
32 Primitive(Primitive),
33 Structure(Box<Structure>),
34 Util(Box<Util>),
35 Custom(String),
36}
37
38#[derive(Debug, Eq, PartialEq)]
39pub enum Conditional {
40 Switch(Switch),
41 Option(DataType),
42}
43
44#[derive(Debug, Eq, PartialEq, Deserialize)]
45pub struct Switch {
46 name: Option<String>,
47 #[serde(rename = "compareTo")]
48 compare_to: String,
49 fields: LinkedHashMap<String, DataType>,
50 default: Option<DataType>,
51}
52
53#[derive(Debug, Eq, PartialEq)]
54pub enum Numeric {
55 Byte { signed: bool },
56 Short { signed: bool, byte_order: ByteOrder },
57 Int { signed: bool, byte_order: ByteOrder },
58 Long { signed: bool, byte_order: ByteOrder },
59 Float { byte_order: ByteOrder },
60 Double { byte_order: ByteOrder },
61 VarInt,
62}
63
64#[derive(Debug, Eq, PartialEq)]
65pub enum ByteOrder {
66 BigEndian,
67 LittleEndian,
68}
69
70#[derive(Debug, Eq, PartialEq, Deserialize)]
71#[serde(rename_all = "lowercase")]
72pub enum Primitive {
73 #[serde(rename = "bool")]
74 Boolean,
75 #[serde(rename = "cstring")]
76 String,
77 Void,
78}
79
80#[derive(Debug, Eq, PartialEq)]
81pub enum Structure {
82 Array(Array),
84 Container(Vec<Field>),
86 Count(Count),
88}
89
90#[derive(Debug, Eq, PartialEq, Deserialize)]
91pub struct Array {
92 #[serde(rename = "countType")]
94 pub count_type: Option<DataType>,
95 pub count: Option<ArrayCount>,
97 #[serde(rename = "type")]
99 pub elements_type: DataType,
100}
101
102#[derive(Debug, Eq, PartialEq, Deserialize)]
103#[serde(untagged)]
104pub enum ArrayCount {
105 FieldReference(String),
107 FixedLength(u32),
109}
110
111#[derive(Debug, Eq, PartialEq, Deserialize)]
112pub struct Field {
113 pub name: Option<String>,
114 #[serde(rename = "type")]
115 pub field_type: DataType,
116 #[serde(rename = "anon")]
118 anonymous: Option<bool>,
119}
120
121#[derive(Debug, Eq, PartialEq, Deserialize)]
122pub struct Count {
123 #[serde(rename = "type")]
125 pub count_type: DataType,
126 #[serde(rename = "countFor")]
128 pub count_for: String,
129}
130
131#[derive(Debug, Eq, PartialEq)]
132pub enum Util {
133 Buffer(Buffer),
134 Mapper(Mapper),
135 Bitfield(Vec<BitField>),
136 PrefixedString { count_type: DataType },
137 Loop(Box<Loop>),
138 TopBitSetTerminatedArray(Box<Structure>),
139}
140
141#[derive(Debug, Eq, PartialEq, Deserialize)]
142pub struct Buffer {
143 #[serde(rename = "countType")]
145 pub count_type: Option<DataType>,
146 pub count: Option<ArrayCount>,
148 pub rest: Option<bool>,
150}
151
152#[derive(Debug, Eq, PartialEq, Deserialize)]
153pub struct Mapper {
154 #[serde(rename = "type")]
155 pub mappings_type: String,
156 pub mappings: LinkedHashMap<String, String>,
157}
158
159#[derive(Debug, Deserialize, PartialEq, Eq)]
160pub struct BitField {
161 pub name: String,
162 pub size: usize,
163 pub signed: bool,
164}
165
166#[derive(Debug, Eq, PartialEq, Deserialize)]
167pub struct Loop {
168 #[serde(rename = "endVal")]
169 pub end_val: u32,
170 #[serde(rename = "type")]
171 pub data_type: DataType,
172}
173
174struct NumericVisitor;
175
176impl<'de> Visitor<'de> for NumericVisitor {
177 type Value = Numeric;
178
179 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
180 formatter.write_str("an valid numeric type string")
181 }
182
183 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
184 where
185 E: de::Error,
186 {
187 match value {
188 "i8" => Ok(Numeric::Byte { signed: true }),
189 "u8" => Ok(Numeric::Byte { signed: false }),
190 "i16" => Ok(Numeric::Short {
191 signed: true,
192 byte_order: ByteOrder::BigEndian,
193 }),
194 "u16" => Ok(Numeric::Short {
195 signed: false,
196 byte_order: ByteOrder::BigEndian,
197 }),
198 "li16" => Ok(Numeric::Short {
199 signed: true,
200 byte_order: ByteOrder::LittleEndian,
201 }),
202 "lu16" => Ok(Numeric::Short {
203 signed: false,
204 byte_order: ByteOrder::LittleEndian,
205 }),
206 "i32" => Ok(Numeric::Int {
207 signed: true,
208 byte_order: ByteOrder::BigEndian,
209 }),
210 "u32" => Ok(Numeric::Int {
211 signed: false,
212 byte_order: ByteOrder::BigEndian,
213 }),
214 "li32" => Ok(Numeric::Int {
215 signed: true,
216 byte_order: ByteOrder::LittleEndian,
217 }),
218 "lu32" => Ok(Numeric::Int {
219 signed: false,
220 byte_order: ByteOrder::LittleEndian,
221 }),
222 "i64" => Ok(Numeric::Long {
223 signed: true,
224 byte_order: ByteOrder::BigEndian,
225 }),
226 "u64" => Ok(Numeric::Long {
227 signed: false,
228 byte_order: ByteOrder::BigEndian,
229 }),
230 "li64" => Ok(Numeric::Long {
231 signed: true,
232 byte_order: ByteOrder::LittleEndian,
233 }),
234 "lu64" => Ok(Numeric::Long {
235 signed: false,
236 byte_order: ByteOrder::LittleEndian,
237 }),
238 "f32" => Ok(Numeric::Float {
239 byte_order: ByteOrder::BigEndian,
240 }),
241 "lf32" => Ok(Numeric::Float {
242 byte_order: ByteOrder::LittleEndian,
243 }),
244 "f64" => Ok(Numeric::Double {
245 byte_order: ByteOrder::BigEndian,
246 }),
247 "lf64" => Ok(Numeric::Double {
248 byte_order: ByteOrder::LittleEndian,
249 }),
250 "varint" => Ok(Numeric::VarInt),
251 _ => Err(de::Error::invalid_value(Unexpected::Str(&value), &self)),
252 }
253 }
254}
255
256impl<'de> Deserialize<'de> for Numeric {
257 fn deserialize<D>(deserializer: D) -> Result<Self, <D>::Error>
258 where
259 D: Deserializer<'de>,
260 {
261 deserializer.deserialize_str(NumericVisitor)
262 }
263}
264
265struct ConditionalVisitor;
266
267impl<'de> Visitor<'de> for ConditionalVisitor {
268 type Value = Conditional;
269
270 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
271 formatter.write_str("an valid `Conditional`")
272 }
273
274 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, <A as SeqAccess<'de>>::Error>
275 where
276 A: SeqAccess<'de>,
277 {
278 let conditional_type: String = seq
279 .next_element()?
280 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
281
282 match conditional_type.as_str() {
283 "switch" => {
284 let switch = seq
285 .next_element()?
286 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
287
288 Ok(Conditional::Switch(switch))
289 }
290 "option" => {
291 let data_type = seq
292 .next_element()?
293 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
294
295 Ok(Conditional::Option(data_type))
296 }
297 unknown_variant => {
298 let mut map: HashMap<String, String> = seq.next_element()?.ok_or_else(|| {
300 de::Error::unknown_variant(unknown_variant, &["switch", "option"])
301 })?;
302
303 if map.len() == 1 {
304 if let Some(compare_to) = map.remove("compareTo") {
305 let switch = Switch {
306 name: Some(unknown_variant.to_owned()),
307 compare_to,
308 fields: LinkedHashMap::new(),
309 default: None,
310 };
311
312 return Ok(Conditional::Switch(switch));
313 }
314 }
315
316 Err(de::Error::unknown_variant(
317 unknown_variant,
318 &["switch", "option"],
319 ))
320 }
321 }
322 }
323}
324
325impl<'de> Deserialize<'de> for Conditional {
326 fn deserialize<D>(deserializer: D) -> Result<Self, <D>::Error>
327 where
328 D: Deserializer<'de>,
329 {
330 deserializer.deserialize_seq(ConditionalVisitor)
331 }
332}
333
334struct StructureVisitor;
335
336impl<'de> Visitor<'de> for StructureVisitor {
337 type Value = Structure;
338
339 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
340 formatter.write_str("an valid `Structure`")
341 }
342
343 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, <A as SeqAccess<'de>>::Error>
344 where
345 A: SeqAccess<'de>,
346 {
347 let struct_type: String = seq
348 .next_element()?
349 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
350
351 match struct_type.as_str() {
352 "container" => {
353 let fields = seq
354 .next_element()?
355 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
356
357 Ok(Structure::Container(fields))
358 }
359 "array" => {
360 let array = seq
361 .next_element()?
362 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
363
364 Ok(Structure::Array(array))
365 }
366 "count" => {
367 let count = seq
368 .next_element()?
369 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
370
371 Ok(Structure::Count(count))
372 }
373 unknown_variant => Err(de::Error::unknown_variant(
374 unknown_variant,
375 &["container", "array", "count"],
376 )),
377 }
378 }
379}
380
381impl<'de> Deserialize<'de> for Structure {
382 fn deserialize<D>(deserializer: D) -> Result<Self, <D>::Error>
383 where
384 D: Deserializer<'de>,
385 {
386 deserializer.deserialize_seq(StructureVisitor)
387 }
388}
389
390struct UtilVisitor;
391
392impl<'de> Visitor<'de> for UtilVisitor {
393 type Value = Util;
394
395 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
396 formatter.write_str("an valid util")
397 }
398
399 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, <A as SeqAccess<'de>>::Error>
400 where
401 A: SeqAccess<'de>,
402 {
403 let util_type: String = seq
404 .next_element()?
405 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
406
407 match util_type.as_str() {
408 "buffer" => {
409 let buffer = seq
410 .next_element()?
411 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
412
413 Ok(Util::Buffer(buffer))
414 }
415 "mapper" => {
416 let mapper = seq
417 .next_element()?
418 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
419
420 Ok(Util::Mapper(mapper))
421 }
422 "bitfield" => {
423 let bitfields = seq
424 .next_element()?
425 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
426
427 Ok(Util::Bitfield(bitfields))
428 }
429 "pstring" => {
430 let mut map: HashMap<String, DataType> = seq
431 .next_element()?
432 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
433
434 let count_type = map
435 .remove("countType")
436 .ok_or_else(|| de::Error::missing_field("countType"))?;
437
438 Ok(Util::PrefixedString { count_type })
439 }
440 "topBitSetTerminatedArray" => {
441 let mut value: HashMap<String, Structure> = seq
442 .next_element()?
443 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
444
445 let structure = value
446 .remove("type")
447 .ok_or_else(|| de::Error::missing_field("type"))?;
448
449 Ok(Util::TopBitSetTerminatedArray(Box::new(structure)))
450 }
451 unknown_variant => {
452 let loop_util: Loop = seq.next_element()?.ok_or_else(|| {
454 de::Error::unknown_variant(
455 unknown_variant,
456 &["buffer", "mapper", "bitfield", "pstring"],
457 )
458 })?;
459
460 Ok(Util::Loop(Box::new(loop_util)))
461 }
462 }
463 }
464}
465
466impl<'de> Deserialize<'de> for Util {
467 fn deserialize<D>(deserializer: D) -> Result<Self, <D>::Error>
468 where
469 D: Deserializer<'de>,
470 {
471 deserializer.deserialize_seq(UtilVisitor)
472 }
473}
474
475#[cfg(test)]
476mod tests {
477 use crate::*;
478 use serde_test::{assert_de_tokens, Token};
479 use std::fs;
480 use std::fs::File;
481
482 #[test]
483 fn test_decode_protocols_data() {
484 let paths = fs::read_dir("test").expect("Failed to open test folder");
485
486 for entry_res in paths.into_iter() {
487 let entry = entry_res.expect("Failed to get test folder entry");
488 let file = File::open(entry.path()).expect("Failed to read file");
489
490 let name = entry
491 .file_name()
492 .into_string()
493 .expect("Failed to get entry name");
494
495 read_protocol(&file).expect(&format!("Failed to read \"{}\" protocol", name));
496 }
497 }
498
499 #[test]
500 fn test_decode_i8() {
501 assert_de_tokens(&Numeric::Byte { signed: true }, &[Token::String("i8")]);
502 }
503
504 #[test]
505 fn test_decode_u8() {
506 assert_de_tokens(&Numeric::Byte { signed: false }, &[Token::String("u8")]);
507 }
508
509 #[test]
510 fn test_decode_i16() {
511 assert_de_tokens(
512 &Numeric::Short {
513 signed: true,
514 byte_order: ByteOrder::BigEndian,
515 },
516 &[Token::String("i16")],
517 );
518 }
519
520 #[test]
521 fn test_decode_u16() {
522 assert_de_tokens(
523 &Numeric::Short {
524 signed: false,
525 byte_order: ByteOrder::BigEndian,
526 },
527 &[Token::String("u16")],
528 );
529 }
530
531 #[test]
532 fn test_decode_li16() {
533 assert_de_tokens(
534 &Numeric::Short {
535 signed: true,
536 byte_order: ByteOrder::LittleEndian,
537 },
538 &[Token::String("li16")],
539 );
540 }
541
542 #[test]
543 fn test_decode_lu16() {
544 assert_de_tokens(
545 &Numeric::Short {
546 signed: false,
547 byte_order: ByteOrder::LittleEndian,
548 },
549 &[Token::String("lu16")],
550 );
551 }
552
553 #[test]
554 fn test_decode_i32() {
555 assert_de_tokens(
556 &Numeric::Int {
557 signed: true,
558 byte_order: ByteOrder::BigEndian,
559 },
560 &[Token::String("i32")],
561 );
562 }
563
564 #[test]
565 fn test_decode_u32() {
566 assert_de_tokens(
567 &Numeric::Int {
568 signed: false,
569 byte_order: ByteOrder::BigEndian,
570 },
571 &[Token::String("u32")],
572 );
573 }
574
575 #[test]
576 fn test_decode_li32() {
577 assert_de_tokens(
578 &Numeric::Int {
579 signed: true,
580 byte_order: ByteOrder::LittleEndian,
581 },
582 &[Token::String("li32")],
583 );
584 }
585
586 #[test]
587 fn test_decode_lu32() {
588 assert_de_tokens(
589 &Numeric::Int {
590 signed: false,
591 byte_order: ByteOrder::LittleEndian,
592 },
593 &[Token::String("lu32")],
594 );
595 }
596
597 #[test]
598 fn test_decode_i64() {
599 assert_de_tokens(
600 &Numeric::Long {
601 signed: true,
602 byte_order: ByteOrder::BigEndian,
603 },
604 &[Token::String("i64")],
605 );
606 }
607
608 #[test]
609 fn test_decode_u64() {
610 assert_de_tokens(
611 &Numeric::Long {
612 signed: false,
613 byte_order: ByteOrder::BigEndian,
614 },
615 &[Token::String("u64")],
616 );
617 }
618
619 #[test]
620 fn test_decode_li64() {
621 assert_de_tokens(
622 &Numeric::Long {
623 signed: true,
624 byte_order: ByteOrder::LittleEndian,
625 },
626 &[Token::String("li64")],
627 );
628 }
629
630 #[test]
631 fn test_decode_lu64() {
632 assert_de_tokens(
633 &Numeric::Long {
634 signed: false,
635 byte_order: ByteOrder::LittleEndian,
636 },
637 &[Token::String("lu64")],
638 );
639 }
640
641 #[test]
642 fn test_decode_f32() {
643 assert_de_tokens(
644 &Numeric::Float {
645 byte_order: ByteOrder::BigEndian,
646 },
647 &[Token::String("f32")],
648 );
649 }
650
651 #[test]
652 fn test_decode_lf32() {
653 assert_de_tokens(
654 &Numeric::Float {
655 byte_order: ByteOrder::LittleEndian,
656 },
657 &[Token::String("lf32")],
658 );
659 }
660
661 #[test]
662 fn test_decode_f64_numeric() {
663 assert_de_tokens(
664 &Numeric::Double {
665 byte_order: ByteOrder::BigEndian,
666 },
667 &[Token::String("f64")],
668 );
669 }
670
671 #[test]
672 fn test_decode_lf64_numeric() {
673 assert_de_tokens(
674 &Numeric::Double {
675 byte_order: ByteOrder::LittleEndian,
676 },
677 &[Token::String("lf64")],
678 );
679 }
680
681 #[test]
682 fn test_decode_boolean() {
683 assert_de_tokens(
684 &Primitive::Boolean,
685 &[
686 Token::Enum { name: "Primitive" },
687 Token::String("bool"),
688 Token::Unit,
689 ],
690 );
691 }
692
693 #[test]
694 fn test_decode_string() {
695 assert_de_tokens(
696 &Primitive::String,
697 &[
698 Token::Enum { name: "Primitive" },
699 Token::String("cstring"),
700 Token::Unit,
701 ],
702 );
703 }
704
705 #[test]
706 fn test_decode_void() {
707 assert_de_tokens(
708 &Primitive::Void,
709 &[
710 Token::Enum { name: "Primitive" },
711 Token::String("void"),
712 Token::Unit,
713 ],
714 );
715 }
716
717 #[test]
718 fn test_decode_numeric_data_type() {
719 assert_de_tokens(
720 &DataType::Numeric(Numeric::Float {
721 byte_order: ByteOrder::BigEndian,
722 }),
723 &[Token::String("f32")],
724 );
725 }
726
727 #[test]
728 fn test_decode_primitive_data_type() {
729 assert_de_tokens(
730 &DataType::Primitive(Primitive::Boolean),
731 &[Token::String("bool")],
732 );
733 }
734
735 #[test]
736 fn test_decode_container_data_type() {
737 let fields = vec![Field {
738 name: Some("serverPort".to_string()),
739 field_type: DataType::Numeric(Numeric::Short {
740 signed: false,
741 byte_order: ByteOrder::BigEndian,
742 }),
743 anonymous: None,
744 }];
745
746 let container = Structure::Container(fields);
747
748 assert_de_tokens(
749 &container,
750 &[
751 Token::Seq { len: Some(2) },
752 Token::String("container"),
753 Token::Seq { len: Some(1) },
754 Token::Struct {
755 name: "Field",
756 len: 2,
757 },
758 Token::Str("name"),
759 Token::Some,
760 Token::String("serverPort"),
761 Token::Str("type"),
762 Token::String("u16"),
763 Token::StructEnd,
764 Token::SeqEnd,
765 Token::SeqEnd,
766 ],
767 );
768 }
769
770 #[test]
771 fn test_decode_container_with_container_data_type() {
772 let inner_container_fields = vec![Field {
773 name: Some("name".to_string()),
774 field_type: DataType::Numeric(Numeric::VarInt),
775 anonymous: None,
776 }];
777
778 let fields = vec![Field {
779 name: Some("inner_container".to_string()),
780 field_type: DataType::Structure(Box::new(Structure::Container(inner_container_fields))),
781 anonymous: None,
782 }];
783
784 let container = Structure::Container(fields);
785
786 assert_de_tokens(
787 &container,
788 &[
789 Token::Seq { len: Some(2) },
790 Token::String("container"),
791 Token::Seq { len: Some(1) },
792 Token::Struct {
793 name: "Field",
794 len: 2,
795 },
796 Token::Str("name"),
797 Token::Some,
798 Token::String("inner_container"),
799 Token::Str("type"),
800 Token::Seq { len: Some(2) },
801 Token::String("container"),
802 Token::Seq { len: Some(1) },
803 Token::Struct {
804 name: "Field",
805 len: 2,
806 },
807 Token::Str("name"),
808 Token::String("name"),
809 Token::Str("type"),
810 Token::String("varint"),
811 Token::StructEnd,
812 Token::SeqEnd,
813 Token::SeqEnd,
814 Token::StructEnd,
815 Token::SeqEnd,
816 Token::SeqEnd,
817 ],
818 );
819 }
820
821 #[test]
822 fn test_decode_array_data_type() {
823 let array = Structure::Array(Array {
824 count_type: Some(DataType::Numeric(Numeric::VarInt)),
825 count: None,
826 elements_type: DataType::Primitive(Primitive::String),
827 });
828
829 assert_de_tokens(
830 &array,
831 &[
832 Token::Seq { len: Some(2) },
833 Token::String("array"),
834 Token::Struct {
835 name: "Array",
836 len: 2,
837 },
838 Token::Str("countType"),
839 Token::Some,
840 Token::String("varint"),
841 Token::Str("type"),
842 Token::String("cstring"),
843 Token::StructEnd,
844 Token::SeqEnd,
845 ],
846 );
847 }
848
849 #[test]
850 fn test_decode_array_with_container_data_type() {
851 let fields = vec![Field {
852 name: Some("name".to_string()),
853 field_type: DataType::Numeric(Numeric::VarInt),
854 anonymous: None,
855 }];
856
857 let array = Structure::Array(Array {
858 count_type: Some(DataType::Numeric(Numeric::VarInt)),
859 count: None,
860 elements_type: DataType::Structure(Box::new(Structure::Container(fields))),
861 });
862
863 assert_de_tokens(
864 &array,
865 &[
866 Token::Seq { len: Some(2) },
867 Token::String("array"),
868 Token::Struct {
869 name: "Array",
870 len: 2,
871 },
872 Token::Str("countType"),
873 Token::Some,
874 Token::String("varint"),
875 Token::Str("type"),
876 Token::Seq { len: Some(2) },
877 Token::String("container"),
878 Token::Seq { len: Some(1) },
879 Token::Struct {
880 name: "Field",
881 len: 2,
882 },
883 Token::Str("name"),
884 Token::String("name"),
885 Token::Str("type"),
886 Token::String("varint"),
887 Token::StructEnd,
888 Token::SeqEnd,
889 Token::SeqEnd,
890 Token::StructEnd,
891 Token::SeqEnd,
892 ],
893 );
894 }
895
896 #[test]
897 fn test_decode_count_data_type() {
898 let count = Structure::Count(Count {
899 count_type: DataType::Numeric(Numeric::VarInt),
900 count_for: "test".to_string(),
901 });
902
903 assert_de_tokens(
904 &count,
905 &[
906 Token::Seq { len: Some(2) },
907 Token::String("count"),
908 Token::Struct {
909 name: "Count",
910 len: 2,
911 },
912 Token::Str("type"),
913 Token::String("varint"),
914 Token::Str("countFor"),
915 Token::String("test"),
916 Token::StructEnd,
917 Token::SeqEnd,
918 ],
919 );
920 }
921
922 #[test]
923 fn test_decode_array_ref_field() {
924 let array = Structure::Array(Array {
925 count_type: None,
926 count: Some(ArrayCount::FieldReference("field".to_string())),
927 elements_type: DataType::Primitive(Primitive::String),
928 });
929
930 assert_de_tokens(
931 &array,
932 &[
933 Token::Seq { len: Some(2) },
934 Token::String("array"),
935 Token::Struct {
936 name: "Array",
937 len: 2,
938 },
939 Token::Str("count"),
940 Token::Some,
941 Token::String("field"),
942 Token::Str("type"),
943 Token::String("cstring"),
944 Token::StructEnd,
945 Token::SeqEnd,
946 ],
947 );
948 }
949
950 #[test]
951 fn test_decode_array_fixed_length() {
952 let array = Structure::Array(Array {
953 count_type: None,
954 count: Some(ArrayCount::FixedLength(4)),
955 elements_type: DataType::Primitive(Primitive::String),
956 });
957
958 assert_de_tokens(
959 &array,
960 &[
961 Token::Seq { len: Some(2) },
962 Token::String("array"),
963 Token::Struct {
964 name: "Array",
965 len: 2,
966 },
967 Token::Str("count"),
968 Token::Some,
969 Token::I32(4),
970 Token::Str("type"),
971 Token::String("cstring"),
972 Token::StructEnd,
973 Token::SeqEnd,
974 ],
975 );
976 }
977
978 #[test]
979 fn test_decode_prefixed_string() {
980 let util = Util::PrefixedString {
981 count_type: DataType::Numeric(Numeric::VarInt),
982 };
983
984 assert_de_tokens(
985 &util,
986 &[
987 Token::Seq { len: Some(2) },
988 Token::Str("pstring"),
989 Token::Struct { name: "", len: 1 },
990 Token::Str("countType"),
991 Token::String("varint"),
992 Token::StructEnd,
993 Token::SeqEnd,
994 ],
995 );
996 }
997
998 #[test]
999 fn test_decode_buffer() {
1000 let util = Util::Buffer(Buffer {
1001 count_type: Some(DataType::Numeric(Numeric::Int {
1002 signed: true,
1003 byte_order: ByteOrder::BigEndian,
1004 })),
1005 count: None,
1006 rest: None,
1007 });
1008
1009 assert_de_tokens(
1010 &util,
1011 &[
1012 Token::Seq { len: Some(2) },
1013 Token::String("buffer"),
1014 Token::Struct {
1015 name: "Buffer",
1016 len: 1,
1017 },
1018 Token::String("countType"),
1019 Token::Some,
1020 Token::String("i32"),
1021 Token::StructEnd,
1022 Token::SeqEnd,
1023 ],
1024 );
1025 }
1026
1027 #[test]
1028 fn test_decode_option() {
1029 let conditional = Conditional::Option(DataType::Numeric(Numeric::Byte { signed: false }));
1030
1031 assert_de_tokens(
1032 &conditional,
1033 &[
1034 Token::Seq { len: Some(2) },
1035 Token::String("option"),
1036 Token::String("u8"),
1037 Token::SeqEnd,
1038 ],
1039 );
1040 }
1041
1042 #[test]
1043 fn test_decode_bad_switch() {
1044 let conditional = Conditional::Switch(Switch {
1045 name: Some("particleData".to_string()),
1046 compare_to: "particleId".to_string(),
1047 fields: Default::default(),
1048 default: None,
1049 });
1050
1051 assert_de_tokens(
1052 &conditional,
1053 &[
1054 Token::Seq { len: Some(2) },
1055 Token::String("particleData"),
1056 Token::Struct { name: "", len: 1 },
1057 Token::String("compareTo"),
1058 Token::String("particleId"),
1059 Token::StructEnd,
1060 Token::SeqEnd,
1061 ],
1062 );
1063 }
1064}