tf_demo_parser/demo/message/
classinfo.rs1use bitbuffer::{BitRead, BitReadSized, BitWrite, BitWriteSized, BitWriteStream, LittleEndian};
2use serde::{Deserialize, Serialize};
3
4use crate::demo::message::stringtable::log_base2;
5use crate::{ReadResult, Stream};
6use std::cmp::min;
7
8#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
9#[derive(BitReadSized, BitWriteSized, Debug, PartialEq, Serialize, Deserialize, Clone)]
10pub struct ClassInfoEntry {
11 #[size = "input_size"]
12 class_id: u16,
13 class_name: String,
14 table_name: String,
15}
16
17#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
18#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
19pub struct ClassInfoMessage {
20 count: u16,
21 create: bool,
22 entries: Vec<ClassInfoEntry>,
23}
24
25impl BitRead<'_, LittleEndian> for ClassInfoMessage {
26 fn read(stream: &mut Stream) -> ReadResult<Self> {
27 let count: u16 = stream.read()?;
28 let create: bool = stream.read()?;
29 let entries = if !create {
30 let mut entries = Vec::with_capacity(min(count, 128) as usize);
31 let bits = log_base2(count) + 1;
32 for _ in 0..count {
33 entries.push(stream.read_sized(bits as usize)?);
34 }
35 entries
36 } else {
37 Vec::new()
38 };
39
40 Ok(ClassInfoMessage {
41 count,
42 create,
43 entries,
44 })
45 }
46}
47
48impl BitWrite<LittleEndian> for ClassInfoMessage {
49 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
50 self.count.write(stream)?;
51 self.create.write(stream)?;
52 if !self.create {
53 let bits = log_base2(self.entries.len()) as usize + 1;
54 for entry in self.entries.iter() {
55 entry.write_sized(stream, bits)?;
56 }
57 }
58
59 Ok(())
60 }
61}
62
63#[test]
64fn test_class_info_roundtrip() {
65 crate::test_roundtrip_write(ClassInfoMessage {
66 count: 8,
67 create: true,
68 entries: Vec::new(),
69 });
70 crate::test_roundtrip_write(ClassInfoMessage {
71 count: 3,
72 create: false,
73 entries: vec![
74 ClassInfoEntry {
75 class_id: 0,
76 class_name: "foo1".to_string(),
77 table_name: "bar1".to_string(),
78 },
79 ClassInfoEntry {
80 class_id: 1,
81 class_name: "foo2".to_string(),
82 table_name: "bar2".to_string(),
83 },
84 ClassInfoEntry {
85 class_id: 2,
86 class_name: "foo3".to_string(),
87 table_name: "bar3".to_string(),
88 },
89 ],
90 });
91}